changeset 14677:2bb5f6ae380f

Merge
author andrew
date Mon, 17 Aug 2020 15:09:48 +0100
parents 9a21ba120101 (current diff) c19e5d127e6c (diff)
children ccb54d552a3b
files
diffstat 1 files changed, 80 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/test/com/sun/jndi/ldap/lib/BaseLdapServer.java	Thu Aug 13 08:38:58 2020 +0100
+++ b/test/com/sun/jndi/ldap/lib/BaseLdapServer.java	Mon Aug 17 15:09:48 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
  * Override the following methods to provide customized behavior
  *
  *     * beforeConnectionHandled
- *     * handleRequest
+ *     * handleRequest (or handleRequestEx)
  *
  * Instances of this class are safe for use by multiple threads.
  */
@@ -119,6 +119,7 @@
         // No need to close socket's streams separately, they will be closed
         // automatically when `socket.close()` is called
         beforeConnectionHandled(socket);
+        ConnWrapper connWrapper = new ConnWrapper(socket);
         try {
             OutputStream out = socket.getOutputStream();
             InputStream in = socket.getInputStream();
@@ -152,7 +153,13 @@
                             "bytes received {0}, expected {1}", new Integer[] { buffer.size(), msgLen});
                     continue;
                 }
-                handleRequest(socket, new LdapMessage(request), out);
+                handleRequestEx(socket, new LdapMessage(request), out, connWrapper);
+                if (connWrapper.updateRequired()) {
+                    Socket wrapper = connWrapper.getWrapper();
+                    in = wrapper.getInputStream();
+                    out = wrapper.getOutputStream();
+                    connWrapper.clearFlag();
+                }
             }
         } catch (Throwable t) {
             if (!isRunning()) {
@@ -168,6 +175,10 @@
                 }
             }
         }
+
+        if (connWrapper.getWrapper() != null) {
+            closeSilently(connWrapper.getWrapper());
+        }
     }
 
     /*
@@ -193,6 +204,40 @@
     }
 
     /*
+     * Called after an LDAP request has been read in `handleConnection()`.
+     *
+     * Override to customize the behavior if you want to handle starttls
+     * extended op, otherwise override handleRequest method instead.
+     *
+     * This is extended handleRequest method which provide possibility to
+     * wrap current socket connection, that's necessary to handle starttls
+     * extended request, here is sample code about how to wrap current socket
+     *
+     * switch (request.getOperation()) {
+     *     ......
+     *     case EXTENDED_REQUEST:
+     *         if (new String(request.getMessage()).endsWith(STARTTLS_REQ_OID)) {
+     *             out.write(STARTTLS_RESPONSE);
+     *             SSLSocket sslSocket = (SSLSocket) sslSocketFactory
+     *                     .createSocket(socket, null, socket.getLocalPort(),
+     *                             false);
+     *             sslSocket.setUseClientMode(false);
+     *             connWrapper.setWrapper(sslSocket);
+     *         }
+     *         break;
+     *     ......
+     * }
+     */
+    protected void handleRequestEx(Socket socket,
+            LdapMessage request,
+            OutputStream out,
+            ConnWrapper connWrapper)
+            throws IOException {
+        // by default, just call handleRequest to keep compatibility
+        handleRequest(socket, request, out);
+    }
+
+    /*
      * To be used by subclasses.
      */
     protected final Logger logger() {
@@ -272,4 +317,36 @@
             resource.close();
         } catch (IOException ignored) { }
     }
+
+    /*
+     * To be used for handling starttls extended request
+     */
+    protected class ConnWrapper {
+        private Socket original;
+        private Socket wrapper;
+        private boolean flag = false;
+
+        public ConnWrapper(Socket socket) {
+            original = socket;
+        }
+
+        public Socket getWrapper() {
+            return wrapper;
+        }
+
+        public void setWrapper(Socket wrapper) {
+            if (wrapper != null && wrapper != original) {
+                this.wrapper = wrapper;
+                flag = true;
+            }
+        }
+
+        public boolean updateRequired() {
+            return flag;
+        }
+
+        public void clearFlag() {
+            flag = false;
+        }
+    }
 }