mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-05 02:02:31 +00:00
8075007: Additional tests for krb5-related cipher suites with unbound server
Reviewed-by: weijun
This commit is contained in:
parent
a4a2831215
commit
64969c0889
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, 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
|
||||
@ -149,6 +149,9 @@ public class KDC {
|
||||
private List<String> conf = new ArrayList<>();
|
||||
|
||||
private Thread thread1, thread2, thread3;
|
||||
private volatile boolean udpConsumerReady = false;
|
||||
private volatile boolean tcpConsumerReady = false;
|
||||
private volatile boolean dispatcherReady = false;
|
||||
DatagramSocket u1 = null;
|
||||
ServerSocket t1 = null;
|
||||
|
||||
@ -1228,6 +1231,7 @@ public class KDC {
|
||||
// The UDP consumer
|
||||
thread1 = new Thread() {
|
||||
public void run() {
|
||||
udpConsumerReady = true;
|
||||
while (true) {
|
||||
try {
|
||||
byte[] inbuf = new byte[8192];
|
||||
@ -1248,6 +1252,7 @@ public class KDC {
|
||||
// The TCP consumer
|
||||
thread2 = new Thread() {
|
||||
public void run() {
|
||||
tcpConsumerReady = true;
|
||||
while (true) {
|
||||
try {
|
||||
Socket socket = tcp.accept();
|
||||
@ -1270,6 +1275,7 @@ public class KDC {
|
||||
// The dispatcher
|
||||
thread3 = new Thread() {
|
||||
public void run() {
|
||||
dispatcherReady = true;
|
||||
while (true) {
|
||||
try {
|
||||
q.take().send();
|
||||
@ -1280,6 +1286,19 @@ public class KDC {
|
||||
};
|
||||
thread3.setDaemon(true);
|
||||
thread3.start();
|
||||
|
||||
// wait for the KDC is ready
|
||||
try {
|
||||
while (!isReady()) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isReady() {
|
||||
return udpConsumerReady && tcpConsumerReady && dispatcherReady;
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
|
||||
134
jdk/test/sun/security/krb5/auto/UnboundSSL.java
Normal file
134
jdk/test/sun/security/krb5/auto/UnboundSSL.java
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025123
|
||||
* @summary Checks if an unbound server can handle connections
|
||||
* only for allowed service principals
|
||||
* @run main/othervm/policy=unbound.ssl.policy UnboundSSL
|
||||
* unbound.ssl.jaas.conf server_star
|
||||
* @run main/othervm/policy=unbound.ssl.policy UnboundSSL
|
||||
* unbound.ssl.jaas.conf server_multiple_principals
|
||||
*/
|
||||
public class UnboundSSL {
|
||||
|
||||
public static void main(String[] args) throws IOException,
|
||||
NoSuchAlgorithmException,LoginException, PrivilegedActionException,
|
||||
InterruptedException {
|
||||
UnboundSSL test = new UnboundSSL();
|
||||
test.start(args[0], args[1]);
|
||||
}
|
||||
|
||||
private void start(String jaacConfigFile, String serverJaasConfig)
|
||||
throws IOException, NoSuchAlgorithmException,LoginException,
|
||||
PrivilegedActionException, InterruptedException {
|
||||
|
||||
// define principals
|
||||
String service1host = "service1." + UnboundSSLUtils.HOST;
|
||||
String service2host = "service2." + UnboundSSLUtils.HOST;
|
||||
String service3host = "service3." + UnboundSSLUtils.HOST;
|
||||
String service1Principal = "host/" + service1host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
String service2Principal = "host/" + service2host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
String service3Principal = "host/" + service3host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
|
||||
Map<String, String> principals = new HashMap<>();
|
||||
principals.put(UnboundSSLUtils.USER_PRINCIPAL,
|
||||
UnboundSSLUtils.USER_PASSWORD);
|
||||
principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null);
|
||||
principals.put(service1Principal, null);
|
||||
principals.put(service2Principal, null);
|
||||
principals.put(service3Principal, null);
|
||||
|
||||
System.setProperty("java.security.krb5.conf",
|
||||
UnboundSSLUtils.KRB5_CONF_FILENAME);
|
||||
|
||||
// start a local KDC instance
|
||||
UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals,
|
||||
UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND);
|
||||
|
||||
System.setProperty("java.security.auth.login.config",
|
||||
UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
|
||||
|
||||
try (final SSLEchoServer server = SSLEchoServer.init(
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
|
||||
|
||||
// start a server instance
|
||||
UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
|
||||
|
||||
// wait for the server is ready
|
||||
while (!server.isReady()) {
|
||||
Thread.sleep(UnboundSSLUtils.DELAY);
|
||||
}
|
||||
|
||||
int port = server.getPort();
|
||||
|
||||
// run clients
|
||||
|
||||
// the server should have a permission to handle a request
|
||||
// with this service principal (there should be an appropriate
|
||||
// javax.security.auth.kerberos.ServicePermission in policy file)
|
||||
System.out.println("Connect: SNI hostname = " + service1host
|
||||
+ ", successful connection is expected");
|
||||
SSLClient.init(UnboundSSLUtils.HOST, port,
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect();
|
||||
|
||||
// the server should NOT have a permission to handle a request
|
||||
// with this service principal (there should be an appropriate
|
||||
// javax.security.auth.kerberos.ServicePermission in policy file)
|
||||
// handshake failures is expected
|
||||
System.out.println("Connect: SNI hostname = " + service2host
|
||||
+ ", connection failure is expected");
|
||||
try {
|
||||
SSLClient.init(UnboundSSLUtils.HOST, port,
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service2host)
|
||||
.connect();
|
||||
throw new RuntimeException("Test failed: "
|
||||
+ "expected IOException not thrown");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Expected exception: " + e);
|
||||
}
|
||||
|
||||
// the server should have a permission to handle a request
|
||||
// with this service principal (there should be an appropriate
|
||||
// javax.security.auth.kerberos.ServicePermission in policy file)
|
||||
System.out.println("Connect: SNI hostname = " + service3host
|
||||
+ ", successful connection is expected");
|
||||
SSLClient.init(UnboundSSLUtils.HOST, port,
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect();
|
||||
}
|
||||
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
}
|
||||
111
jdk/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java
Normal file
111
jdk/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025123
|
||||
* @summary Checks if an unbound server pick up a correct key from keytab
|
||||
* @run main/othervm UnboundSSLMultipleKeys
|
||||
* unbound.ssl.jaas.conf server_star
|
||||
* @run main/othervm UnboundSSLMultipleKeys
|
||||
* unbound.ssl.jaas.conf server_multiple_principals
|
||||
*/
|
||||
public class UnboundSSLMultipleKeys {
|
||||
|
||||
public static void main(String[] args)
|
||||
throws IOException, NoSuchAlgorithmException, LoginException,
|
||||
PrivilegedActionException, InterruptedException {
|
||||
UnboundSSLMultipleKeys test = new UnboundSSLMultipleKeys();
|
||||
test.start(args[0], args[1]);
|
||||
}
|
||||
|
||||
private void start(String jaacConfigFile, String serverJaasConfig)
|
||||
throws IOException, NoSuchAlgorithmException, LoginException,
|
||||
PrivilegedActionException, InterruptedException {
|
||||
|
||||
// define service principals
|
||||
String service1host = "service1." + UnboundSSLUtils.HOST;
|
||||
String service2host = "service2." + UnboundSSLUtils.HOST;
|
||||
String service3host = "service3." + UnboundSSLUtils.HOST;
|
||||
String service1Principal = "host/" + service1host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
String service2Principal = "host/" + service2host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
String service3Principal = "host/" + service3host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
|
||||
Map<String, String> principals = new HashMap<>();
|
||||
principals.put(UnboundSSLUtils.USER_PRINCIPAL,
|
||||
UnboundSSLUtils.USER_PASSWORD);
|
||||
principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, "pass");
|
||||
principals.put(service1Principal, "pass0");
|
||||
principals.put(service1Principal, "pass1");
|
||||
principals.put(service1Principal, "pass2");
|
||||
principals.put(service2Principal, "pass");
|
||||
principals.put(service3Principal, "pass");
|
||||
|
||||
System.setProperty("java.security.krb5.conf",
|
||||
UnboundSSLUtils.KRB5_CONF_FILENAME);
|
||||
|
||||
/*
|
||||
* Start a local KDC instance
|
||||
*
|
||||
* Keytab file contains 3 keys (with different KVNO) for service1
|
||||
* principal, but password for only one key is the same with the record
|
||||
* for service1 principal in KDC.
|
||||
*/
|
||||
UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals,
|
||||
UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND);
|
||||
|
||||
System.setProperty("java.security.auth.login.config",
|
||||
UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
|
||||
|
||||
// start an SSL server instance
|
||||
try (SSLEchoServer server = SSLEchoServer.init(
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
|
||||
|
||||
UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
|
||||
|
||||
// wait for the server is ready
|
||||
while (!server.isReady()) {
|
||||
Thread.sleep(UnboundSSLUtils.DELAY);
|
||||
}
|
||||
|
||||
// run a client
|
||||
System.out.println("Successful connection is expected");
|
||||
SSLClient.init(UnboundSSLUtils.HOST, server.getPort(),
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect();
|
||||
}
|
||||
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
|
||||
}
|
||||
119
jdk/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java
Normal file
119
jdk/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025123
|
||||
* @summary Checks if an unbound server uses a service principal
|
||||
* from sun.security.krb5.principal system property if specified
|
||||
* @run main/othervm UnboundSSLPrincipalProperty
|
||||
* unbound.ssl.jaas.conf server_star
|
||||
* @run main/othervm UnboundSSLPrincipalProperty
|
||||
* unbound.ssl.jaas.conf server_multiple_principals
|
||||
*/
|
||||
public class UnboundSSLPrincipalProperty {
|
||||
|
||||
public static void main(String[] args) throws IOException,
|
||||
NoSuchAlgorithmException,LoginException, PrivilegedActionException,
|
||||
InterruptedException {
|
||||
UnboundSSLPrincipalProperty test = new UnboundSSLPrincipalProperty();
|
||||
test.start(args[0], args[1]);
|
||||
}
|
||||
|
||||
public void start(String jaacConfigFile, String serverJaasConfig)
|
||||
throws IOException, NoSuchAlgorithmException,LoginException,
|
||||
PrivilegedActionException, InterruptedException {
|
||||
|
||||
// define principals
|
||||
String service1host = "service1." + UnboundSSLUtils.HOST;
|
||||
String service3host = "service3." + UnboundSSLUtils.HOST;
|
||||
String service1Principal = "host/" + service1host + "@"
|
||||
+ UnboundSSLUtils.REALM;
|
||||
String service3Principal = "host/" + service3host
|
||||
+ "@" + UnboundSSLUtils.REALM;
|
||||
|
||||
Map<String, String> principals = new HashMap<>();
|
||||
principals.put(UnboundSSLUtils.USER_PRINCIPAL,
|
||||
UnboundSSLUtils.USER_PASSWORD);
|
||||
principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null);
|
||||
principals.put(service1Principal, null);
|
||||
principals.put(service3Principal, null);
|
||||
|
||||
System.setProperty("java.security.krb5.conf",
|
||||
UnboundSSLUtils.KRB5_CONF_FILENAME);
|
||||
|
||||
// start a local KDC instance
|
||||
UnboundSSLUtils.startKDC(UnboundSSLUtils.REALM, principals,
|
||||
UnboundSSLUtils.KTAB_FILENAME, UnboundSSLUtils.KtabMode.APPEND);
|
||||
|
||||
System.setProperty("java.security.auth.login.config",
|
||||
UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
|
||||
|
||||
// start an SSL server instance
|
||||
try (final SSLEchoServer server = SSLEchoServer.init(
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
|
||||
|
||||
// specify a service principal for the server
|
||||
System.setProperty("sun.security.krb5.principal",
|
||||
service3Principal);
|
||||
|
||||
UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
|
||||
|
||||
// wait for the server is ready
|
||||
while (!server.isReady()) {
|
||||
Thread.sleep(UnboundSSLUtils.DELAY);
|
||||
}
|
||||
|
||||
int port = server.getPort();
|
||||
|
||||
// connetion failure is expected
|
||||
// since service3 principal was specified to use by the server
|
||||
System.out.println("Connect: SNI hostname = " + service1host
|
||||
+ ", connection failure is expected");
|
||||
try {
|
||||
SSLClient.init(UnboundSSLUtils.HOST, port,
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service1host)
|
||||
.connect();
|
||||
throw new RuntimeException("Test failed: "
|
||||
+ "expected IOException not thrown");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Expected exception: " + e);
|
||||
}
|
||||
|
||||
System.out.println("Connect: SNI hostname = " + service3host
|
||||
+ ", successful connection is expected");
|
||||
SSLClient.init(UnboundSSLUtils.HOST, port,
|
||||
UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect();
|
||||
}
|
||||
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
}
|
||||
353
jdk/test/sun/security/krb5/auto/UnboundSSLUtils.java
Normal file
353
jdk/test/sun/security/krb5/auto/UnboundSSLUtils.java
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.SNIHostName;
|
||||
import javax.net.ssl.SNIMatcher;
|
||||
import javax.net.ssl.SNIServerName;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
/*
|
||||
* Helper class for unbound krb5 tests.
|
||||
*/
|
||||
class UnboundSSLUtils {
|
||||
|
||||
static enum KtabMode { APPEND, EXISTING };
|
||||
|
||||
static final String KTAB_FILENAME = "krb5.keytab.data";
|
||||
static final String HOST = "localhost";
|
||||
static final String REALM = "TEST.REALM";
|
||||
static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
|
||||
static final String TEST_SRC = System.getProperty("test.src", ".");
|
||||
static final String TLS_KRB5_FILTER = "TLS_KRB5";
|
||||
static final String USER = "USER";
|
||||
static final String USER_PASSWORD = "password";
|
||||
static final String FS = System.getProperty("file.separator");
|
||||
static final String SNI_PATTERN = ".*";
|
||||
static final String USER_PRINCIPAL = USER + "@" + REALM;
|
||||
static final String KRB5_CONF_FILENAME = "krb5.conf";
|
||||
static final int DELAY = 1000;
|
||||
|
||||
static String[] filterStringArray(String[] src, String filter) {
|
||||
return Arrays.stream(src).filter((item) -> item.startsWith(filter))
|
||||
.toArray(size -> new String[size]);
|
||||
}
|
||||
|
||||
/*
|
||||
* The method does JAAS login,
|
||||
* and runs an SSL server in the JAAS context.
|
||||
*/
|
||||
static void startServerWithJaas(final SSLEchoServer server,
|
||||
String config) throws LoginException, PrivilegedActionException {
|
||||
LoginContext context = new LoginContext(config);
|
||||
context.login();
|
||||
System.out.println("Server: successful authentication");
|
||||
Subject.doAs(context.getSubject(),
|
||||
(PrivilegedExceptionAction<Object>) () -> {
|
||||
SSLEchoServer.startServer(server);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Start a KDC server:
|
||||
* - create a KDC instance
|
||||
* - create Kerberos principals
|
||||
* - save Kerberos configuration
|
||||
* - save keys to keytab file
|
||||
* - no pre-auth required
|
||||
*/
|
||||
static void startKDC(String realm, Map<String, String> principals,
|
||||
String ktab, KtabMode mode) {
|
||||
try {
|
||||
KDC kdc = KDC.create(realm, HOST, 0, true);
|
||||
kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE);
|
||||
if (principals != null) {
|
||||
for (Map.Entry<String, String> entry : principals.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String password = entry.getValue();
|
||||
if (password == null || password.isEmpty()) {
|
||||
System.out.println("KDC: add a principal '" + name +
|
||||
"' with a random password");
|
||||
kdc.addPrincipalRandKey(name);
|
||||
} else {
|
||||
System.out.println("KDC: add a principal '" + name +
|
||||
"' with '" + password + "' password");
|
||||
kdc.addPrincipal(name, password.toCharArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KDC.saveConfig(KRB5_CONF_FILENAME, kdc);
|
||||
|
||||
if (ktab != null) {
|
||||
File ktabFile = new File(ktab);
|
||||
if (mode == KtabMode.APPEND) {
|
||||
if (ktabFile.exists()) {
|
||||
System.out.println("KDC: append keys to an exising " +
|
||||
"keytab file " + ktab);
|
||||
kdc.appendKtab(ktab);
|
||||
} else {
|
||||
System.out.println("KDC: create a new keytab file " +
|
||||
ktab);
|
||||
kdc.writeKtab(ktab);
|
||||
}
|
||||
} else if (mode == KtabMode.EXISTING) {
|
||||
System.out.println("KDC: use an existing keytab file "
|
||||
+ ktab);
|
||||
} else {
|
||||
throw new RuntimeException("KDC: unsupported keytab mode: "
|
||||
+ mode);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("KDC: started on " + HOST + ":" + kdc.getPort()
|
||||
+ " with '" + realm + "' realm");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("KDC: unexpected exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SSLClient {
|
||||
|
||||
private final static byte[][] arrays = {
|
||||
new byte[] {-1, 0, 2},
|
||||
new byte[] {}
|
||||
};
|
||||
|
||||
private final SSLSocket socket;
|
||||
|
||||
private SSLClient(SSLSocket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
void connect() throws IOException {
|
||||
System.out.println("Client: connect to server");
|
||||
try (BufferedInputStream bis = new BufferedInputStream(
|
||||
socket.getInputStream());
|
||||
BufferedOutputStream bos = new BufferedOutputStream(
|
||||
socket.getOutputStream())) {
|
||||
|
||||
for (byte[] bytes : arrays) {
|
||||
System.out.println("Client: send byte array: "
|
||||
+ Arrays.toString(bytes));
|
||||
|
||||
bos.write(bytes);
|
||||
bos.flush();
|
||||
|
||||
byte[] recieved = new byte[bytes.length];
|
||||
int read = bis.read(recieved, 0, bytes.length);
|
||||
if (read < 0) {
|
||||
throw new IOException("Client: couldn't read a response");
|
||||
}
|
||||
|
||||
System.out.println("Client: recieved byte array: "
|
||||
+ Arrays.toString(recieved));
|
||||
|
||||
if (!Arrays.equals(bytes, recieved)) {
|
||||
throw new IOException("Client: sent byte array "
|
||||
+ "is not equal with recieved byte array");
|
||||
}
|
||||
}
|
||||
socket.getSession().invalidate();
|
||||
} finally {
|
||||
if (!socket.isClosed()) {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SSLClient init(String host, int port, String cipherSuiteFilter,
|
||||
String sniHostName) throws NoSuchAlgorithmException, IOException {
|
||||
SSLContext sslContext = SSLContext.getDefault();
|
||||
SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();
|
||||
SSLSocket socket = (SSLSocket) ssf.createSocket(host, port);
|
||||
SSLParameters params = new SSLParameters();
|
||||
|
||||
if (cipherSuiteFilter != null) {
|
||||
String[] cipherSuites = UnboundSSLUtils.filterStringArray(
|
||||
ssf.getSupportedCipherSuites(), cipherSuiteFilter);
|
||||
System.out.println("Client: enabled cipher suites: "
|
||||
+ Arrays.toString(cipherSuites));
|
||||
params.setCipherSuites(cipherSuites);
|
||||
}
|
||||
|
||||
if (sniHostName != null) {
|
||||
System.out.println("Client: set SNI hostname: " + sniHostName);
|
||||
SNIHostName serverName = new SNIHostName(sniHostName);
|
||||
List<SNIServerName> serverNames = new ArrayList<>();
|
||||
serverNames.add(serverName);
|
||||
params.setServerNames(serverNames);
|
||||
}
|
||||
|
||||
socket.setSSLParameters(params);
|
||||
|
||||
return new SSLClient(socket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SSLEchoServer implements Runnable, AutoCloseable {
|
||||
|
||||
private final SSLServerSocket ssocket;
|
||||
private volatile boolean stopped = false;
|
||||
private volatile boolean ready = false;
|
||||
|
||||
/*
|
||||
* Starts the server in a separate thread.
|
||||
*/
|
||||
static void startServer(SSLEchoServer server) {
|
||||
Thread serverThread = new Thread(server, "SSL echo server thread");
|
||||
serverThread.setDaemon(true);
|
||||
serverThread.start();
|
||||
}
|
||||
|
||||
private SSLEchoServer(SSLServerSocket ssocket) {
|
||||
this.ssocket = ssocket;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main server loop.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Server: started");
|
||||
while (!stopped) {
|
||||
ready = true;
|
||||
try (SSLSocket socket = (SSLSocket) ssocket.accept()) {
|
||||
System.out.println("Server: client connection accepted");
|
||||
try (
|
||||
BufferedInputStream bis = new BufferedInputStream(
|
||||
socket.getInputStream());
|
||||
BufferedOutputStream bos = new BufferedOutputStream(
|
||||
socket.getOutputStream())
|
||||
) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
while ((read = bis.read(buffer)) > 0) {
|
||||
bos.write(buffer, 0, read);
|
||||
System.out.println("Server: recieved " + read
|
||||
+ " bytes: "
|
||||
+ Arrays.toString(Arrays.copyOf(buffer, read)));
|
||||
bos.flush();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (stopped) {
|
||||
// stopped == true means that stop() method was called,
|
||||
// so just ignore the exception, and finish the loop
|
||||
break;
|
||||
}
|
||||
System.out.println("Server: couldn't accept client connection: "
|
||||
+ e);
|
||||
}
|
||||
}
|
||||
System.out.println("Server: finished");
|
||||
}
|
||||
|
||||
boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
stopped = true;
|
||||
ready = false;
|
||||
|
||||
// close the server socket to interupt accept() method
|
||||
try {
|
||||
if (!ssocket.isClosed()) {
|
||||
ssocket.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
stop();
|
||||
}
|
||||
|
||||
int getPort() {
|
||||
return ssocket.getLocalPort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates server instance.
|
||||
*
|
||||
* @param cipherSuiteFilter Filter for enabled cipher suites
|
||||
* @param sniMatcherPattern Pattern for SNI server hame
|
||||
*/
|
||||
static SSLEchoServer init(String cipherSuiteFilter,
|
||||
String sniPattern) throws NoSuchAlgorithmException, IOException {
|
||||
SSLContext context = SSLContext.getDefault();
|
||||
SSLServerSocketFactory ssf =
|
||||
(SSLServerSocketFactory) context.getServerSocketFactory();
|
||||
SSLServerSocket ssocket =
|
||||
(SSLServerSocket) ssf.createServerSocket(0);
|
||||
|
||||
// specify enabled cipher suites
|
||||
if (cipherSuiteFilter != null) {
|
||||
String[] ciphersuites = UnboundSSLUtils.filterStringArray(
|
||||
ssf.getSupportedCipherSuites(), cipherSuiteFilter);
|
||||
System.out.println("Server: enabled cipher suites: "
|
||||
+ Arrays.toString(ciphersuites));
|
||||
ssocket.setEnabledCipherSuites(ciphersuites);
|
||||
}
|
||||
|
||||
// specify SNI matcher pattern
|
||||
if (sniPattern != null) {
|
||||
System.out.println("Server: set SNI matcher: " + sniPattern);
|
||||
SNIMatcher matcher = SNIHostName.createSNIMatcher(sniPattern);
|
||||
List<SNIMatcher> matchers = new ArrayList<>();
|
||||
matchers.add(matcher);
|
||||
SSLParameters params = ssocket.getSSLParameters();
|
||||
params.setSNIMatchers(matchers);
|
||||
ssocket.setSSLParameters(params);
|
||||
}
|
||||
|
||||
return new SSLEchoServer(ssocket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
40
jdk/test/sun/security/krb5/auto/unbound.ssl.jaas.conf
Normal file
40
jdk/test/sun/security/krb5/auto/unbound.ssl.jaas.conf
Normal file
@ -0,0 +1,40 @@
|
||||
com.sun.net.ssl.client {
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
principal="USER@TEST.REALM"
|
||||
doNotPrompt=true
|
||||
useKeyTab=true
|
||||
keyTab="krb5.keytab.data";
|
||||
};
|
||||
|
||||
server_star {
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
principal="*"
|
||||
isInitiator=false
|
||||
useKeyTab=true
|
||||
keyTab="krb5.keytab.data"
|
||||
storeKey=true;
|
||||
};
|
||||
|
||||
server_multiple_principals {
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
principal="host/service1.localhost@TEST.REALM"
|
||||
isInitiator=false
|
||||
useKeyTab=true
|
||||
keyTab="krb5.keytab.data"
|
||||
storeKey=true;
|
||||
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
principal="host/service2.localhost@TEST.REALM"
|
||||
isInitiator=false
|
||||
useKeyTab=true
|
||||
keyTab="krb5.keytab.data"
|
||||
storeKey=true;
|
||||
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
principal="host/service3.localhost@TEST.REALM"
|
||||
isInitiator=false
|
||||
useKeyTab=true
|
||||
keyTab="krb5.keytab.data"
|
||||
storeKey=true;
|
||||
};
|
||||
|
||||
26
jdk/test/sun/security/krb5/auto/unbound.ssl.policy
Normal file
26
jdk/test/sun/security/krb5/auto/unbound.ssl.policy
Normal file
@ -0,0 +1,26 @@
|
||||
grant {
|
||||
permission java.util.PropertyPermission "*", "read,write";
|
||||
permission java.net.SocketPermission "*:*", "listen,resolve,accept,connect";
|
||||
permission java.io.FilePermission "*", "read,write,delete";
|
||||
permission java.lang.RuntimePermission "accessDeclaredMembers";
|
||||
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.*";
|
||||
permission javax.security.auth.AuthPermission "doAs";
|
||||
permission javax.security.auth.AuthPermission "getSubject";
|
||||
permission javax.security.auth.AuthPermission
|
||||
"createLoginContext.server_star";
|
||||
permission javax.security.auth.AuthPermission
|
||||
"createLoginContext.server_multiple_principals";
|
||||
permission javax.security.auth.AuthPermission "modifyPrincipals";
|
||||
permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab java.security.Principal \"krb5.keytab.data\"", "read";
|
||||
|
||||
// clients have a permission to use all service principals
|
||||
permission javax.security.auth.kerberos.ServicePermission "*", "initiate";
|
||||
|
||||
// server has a service permission
|
||||
// to accept only service1 and service3 principals
|
||||
permission javax.security.auth.kerberos.ServicePermission
|
||||
"host/service1.localhost@TEST.REALM", "accept";
|
||||
permission javax.security.auth.kerberos.ServicePermission
|
||||
"host/service3.localhost@TEST.REALM", "accept";
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user