1 import java.io.File;
   2 import java.io.FileInputStream;
   3 import java.io.FileOutputStream;
   4 import java.io.IOException;
   5 import java.security.Permission;
   6 import java.util.Hashtable;
   7 import java.util.concurrent.Callable;
   8 import java.util.concurrent.FutureTask;
   9 
  10 import javax.naming.Context;
  11 import javax.naming.InitialContext;
  12 import javax.naming.NamingException;
  13 import javax.naming.directory.InitialDirContext;
  14 import javax.naming.directory.SearchControls;
  15 import javax.naming.spi.ldap.LdapDnsProvider;
  16 
  17 /**
  18  * @test
  19  * @bug 8160768
  20  * @summary ctx provider tests for ldap
  21  * @modules java.naming/com.sun.jndi.ldap
  22  * @compile dnsprovider/TestDnsProvider.java
  23  * @run main/othervm LdapDnsProviderTest
  24  * @run main/othervm LdapDnsProviderTest nosm
  25  * @run main/othervm LdapDnsProviderTest smnodns
  26  * @run main/othervm LdapDnsProviderTest smdns
  27  */
  28 class DNSSecurityManager extends SecurityManager {
  29     private boolean dnsProvider = false;
  30 
  31     public void setAllowDnsProvider(boolean allow) {
  32         dnsProvider = allow;
  33     }
  34 
  35     @Override
  36     public void checkPermission(Permission p) {
  37         if (p.getName().equals(LdapDnsProvider.DNSPROVIDER_PERMISSION.getName())
  38                 && !dnsProvider)
  39         {
  40             throw new SecurityException(p.getName());
  41         }
  42     }
  43 }
  44 
  45 class ProviderTest implements Callable<Boolean> {
  46 
  47     private final String url;
  48     private final String expected;
  49     private final Hashtable<String, String> env = new Hashtable<>(11);
  50 
  51     public ProviderTest(String url, String expected) throws IOException {
  52         this.url = url;
  53         this.expected = expected;
  54         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  55     }
  56 
  57     boolean shutItDown(InitialContext ctx) {
  58         try {
  59             if (ctx != null) ctx.close();
  60             return true;
  61         } catch (NamingException ex) {
  62             return false;
  63         }
  64     }
  65 
  66     public Boolean call() {
  67         boolean passed;
  68         InitialContext ctx = null;
  69 
  70         env.put(Context.PROVIDER_URL, url);
  71 
  72         try {
  73             ctx = new InitialDirContext(env);
  74             SearchControls scl = new SearchControls();
  75             scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
  76             ((InitialDirContext)ctx).search(
  77                     "ou=People,o=Test", "(objectClass=*)", scl);
  78             throw new RuntimeException("Search should not complete");
  79         } catch (NamingException e) {
  80             System.out.println(e);
  81             e.printStackTrace();
  82             passed = e.toString().contains(expected);
  83         } finally {
  84             shutItDown(ctx);
  85         }
  86         return passed;
  87     }
  88 }
  89 
  90 public class LdapDnsProviderTest {
  91 
  92     private static final String TEST_CLASSES =
  93             System.getProperty("test.classes", ".");
  94     private static final String TEST_SRC =
  95             System.getProperty("test.src", ".");
  96 
  97 
  98     public static void copyFile(File srcFile, File dstFile)
  99         throws IOException
 100     {
 101         try (FileInputStream src = new FileInputStream(srcFile);
 102              FileOutputStream dst = new FileOutputStream(dstFile)) {
 103             byte[] buf = new byte[32768];
 104             while (true) {
 105                 int count = src.read(buf);
 106                 if (count < 0) {
 107                     break;
 108                 }
 109                 dst.write(buf, 0, count);
 110             }
 111         }
 112     }
 113 
 114     public static void installServiceConfigurationFile() {
 115         String filename = "javax.naming.spi.ldap.LdapDnsProvider";
 116 
 117         File dstDir = new File(TEST_CLASSES, "META-INF/services");
 118         if (!dstDir.exists()) {
 119             if (!dstDir.mkdirs()) {
 120                 throw new RuntimeException(
 121                     "could not create META-INF/services directory " + dstDir);
 122             }
 123         }
 124         File dstFile = new File(dstDir, filename);
 125 
 126         File srcDir = new File(TEST_SRC);
 127         File srcFile = new File(srcDir, filename);
 128 
 129         try {
 130             copyFile(srcFile, dstFile);
 131         } catch (IOException e) {
 132             throw new RuntimeException("could not install " + dstFile, e);
 133         }
 134     }
 135 
 136     public static void main(String[] args) throws Exception {
 137         if (args.length > 0 && args[0].equals("nosm")) {
 138             // no security manager, serviceloader
 139             installServiceConfigurationFile();
 140             runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
 141         } else if (args.length > 0 && args[0].equals("smnodns")) {
 142             // security manager & serviceloader
 143             installServiceConfigurationFile();
 144             // install security manager
 145             System.setSecurityManager(new DNSSecurityManager());
 146             runTest("ldap:///dc=example,dc=com", "ldapDnsProvider");
 147         } else if (args.length > 0 && args[0].equals("smdns")) {
 148             // security manager & serviceloader
 149             DNSSecurityManager sm = new DNSSecurityManager();
 150             installServiceConfigurationFile();
 151             // install security manager
 152             System.setSecurityManager(sm);
 153             sm.setAllowDnsProvider(true);
 154             runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
 155         } else {
 156             // no security manager, no serviceloader
 157 
 158             // DefaultLdapDnsProvider
 159             File f = new File(
 160                     TEST_CLASSES, "META-INF/services/javax.naming.spi.ldap.LdapDnsProvider");
 161             if (f.exists()) {
 162                 f.delete();
 163             }
 164 
 165             // no SecurityManager
 166             runTest("ldap:///dc=example,dc=com", "localhost:389");
 167             runTest("ldap://localhost/dc=example,dc=com", "localhost:389");
 168             runTest("ldap://localhost:111/dc=example,dc=com", "localhost:111");
 169             runTest("ldaps://localhost:111/dc=example,dc=com", "localhost:111");
 170             runTest("ldaps://localhost/dc=example,dc=com", "localhost:636");
 171         }
 172     }
 173 
 174     private static boolean runTest(String url, String expected) throws Exception {
 175         FutureTask<Boolean> future =
 176             new FutureTask<>(
 177                     new ProviderTest(url, expected));
 178         new Thread(future).start();
 179 
 180         while (!future.isDone()) {
 181             if (future.get()) {
 182                 return true;
 183             }
 184         }
 185         throw new AssertionError("FAILED: " + expected);
 186     }
 187 
 188 }
 189