mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-20 15:25:27 +00:00
8005523: Unbound krb5 for TLS
Reviewed-by: xuelei
This commit is contained in:
parent
95aba47819
commit
70b23a07be
@ -86,10 +86,10 @@ public class KerberosClientKeyExchange extends HandshakeMessage {
|
||||
|
||||
public KerberosClientKeyExchange(ProtocolVersion protocolVersion,
|
||||
ProtocolVersion clientVersion, SecureRandom rand,
|
||||
HandshakeInStream input, SecretKey[] serverKeys) throws IOException {
|
||||
HandshakeInStream input, AccessControlContext acc, Object serverKeys) throws IOException {
|
||||
|
||||
if (impl != null) {
|
||||
init(protocolVersion, clientVersion, rand, input, serverKeys);
|
||||
init(protocolVersion, clientVersion, rand, input, acc, serverKeys);
|
||||
} else {
|
||||
throw new IllegalStateException("Kerberos is unavailable");
|
||||
}
|
||||
@ -126,10 +126,10 @@ public class KerberosClientKeyExchange extends HandshakeMessage {
|
||||
|
||||
public void init(ProtocolVersion protocolVersion,
|
||||
ProtocolVersion clientVersion, SecureRandom rand,
|
||||
HandshakeInStream input, SecretKey[] serverKeys) throws IOException {
|
||||
HandshakeInStream input, AccessControlContext acc, Object ServiceCreds) throws IOException {
|
||||
|
||||
if (impl != null) {
|
||||
impl.init(protocolVersion, clientVersion, rand, input, serverKeys);
|
||||
impl.init(protocolVersion, clientVersion, rand, input, acc, ServiceCreds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -94,18 +94,18 @@ public final class Krb5Helper {
|
||||
/**
|
||||
* Returns the KerberosKeys for the default server-side principal.
|
||||
*/
|
||||
public static SecretKey[] getServerKeys(AccessControlContext acc)
|
||||
public static Object getServiceCreds(AccessControlContext acc)
|
||||
throws LoginException {
|
||||
ensureAvailable();
|
||||
return proxy.getServerKeys(acc);
|
||||
return proxy.getServiceCreds(acc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server-side principal name associated with the KerberosKey.
|
||||
*/
|
||||
public static String getServerPrincipalName(SecretKey kerberosKey) {
|
||||
public static String getServerPrincipalName(Object serviceCreds) {
|
||||
ensureAvailable();
|
||||
return proxy.getServerPrincipalName(kerberosKey);
|
||||
return proxy.getServerPrincipalName(serviceCreds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,4 +124,12 @@ public final class Krb5Helper {
|
||||
ensureAvailable();
|
||||
return proxy.getServicePermission(principalName, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Subject might contain creds for princ.
|
||||
*/
|
||||
public static boolean isRelated(Subject subject, Principal princ) {
|
||||
ensureAvailable();
|
||||
return proxy.isRelated(subject, princ);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,14 +50,14 @@ public interface Krb5Proxy {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the KerberosKeys for the default server-side principal.
|
||||
* Returns the Kerberos ServiceCreds for the default server-side principal.
|
||||
*/
|
||||
SecretKey[] getServerKeys(AccessControlContext acc) throws LoginException;
|
||||
Object getServiceCreds(AccessControlContext acc) throws LoginException;
|
||||
|
||||
/**
|
||||
* Returns the server-side principal name associated with the KerberosKey.
|
||||
*/
|
||||
String getServerPrincipalName(SecretKey kerberosKey);
|
||||
String getServerPrincipalName(Object serviceCreds);
|
||||
|
||||
/**
|
||||
* Returns the hostname embedded in the principal name.
|
||||
@ -68,4 +68,9 @@ public interface Krb5Proxy {
|
||||
* Returns a ServicePermission for the principal name and action.
|
||||
*/
|
||||
Permission getServicePermission(String principalName, String action);
|
||||
|
||||
/**
|
||||
* Determines if the Subject might contain creds for princ.
|
||||
*/
|
||||
boolean isRelated(Subject subject, Principal princ);
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ final class ServerHandshaker extends Handshaker {
|
||||
private X509Certificate[] certs;
|
||||
private PrivateKey privateKey;
|
||||
|
||||
private SecretKey[] kerberosKeys;
|
||||
private Object serviceCreds;
|
||||
|
||||
// flag to check for clientCertificateVerify message
|
||||
private boolean needClientVerify = false;
|
||||
@ -200,7 +200,8 @@ final class ServerHandshaker extends Handshaker {
|
||||
clientRequestedVersion,
|
||||
sslContext.getSecureRandom(),
|
||||
input,
|
||||
kerberosKeys));
|
||||
this.getAccSE(),
|
||||
serviceCreds));
|
||||
break;
|
||||
case K_DHE_RSA:
|
||||
case K_DHE_DSS:
|
||||
@ -543,18 +544,15 @@ final class ServerHandshaker extends Handshaker {
|
||||
|
||||
if (subject != null) {
|
||||
// Eliminate dependency on KerberosPrincipal
|
||||
Set<Principal> principals =
|
||||
subject.getPrincipals(Principal.class);
|
||||
if (!principals.contains(localPrincipal)) {
|
||||
resumingSession = false;
|
||||
if (debug != null && Debug.isOn("session")) {
|
||||
System.out.println("Subject identity" +
|
||||
" is not the same");
|
||||
}
|
||||
} else {
|
||||
if (Krb5Helper.isRelated(subject, localPrincipal)) {
|
||||
if (debug != null && Debug.isOn("session"))
|
||||
System.out.println("Subject identity" +
|
||||
" is same");
|
||||
System.out.println("Subject can" +
|
||||
" provide creds for princ");
|
||||
} else {
|
||||
resumingSession = false;
|
||||
if (debug != null && Debug.isOn("session"))
|
||||
System.out.println("Subject cannot" +
|
||||
" provide creds for princ");
|
||||
}
|
||||
} else {
|
||||
resumingSession = false;
|
||||
@ -1316,49 +1314,51 @@ final class ServerHandshaker extends Handshaker {
|
||||
* @return true if successful, false if not available or invalid
|
||||
*/
|
||||
private boolean setupKerberosKeys() {
|
||||
if (kerberosKeys != null) {
|
||||
if (serviceCreds != null) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
final AccessControlContext acc = getAccSE();
|
||||
kerberosKeys = AccessController.doPrivileged(
|
||||
serviceCreds = AccessController.doPrivileged(
|
||||
// Eliminate dependency on KerberosKey
|
||||
new PrivilegedExceptionAction<SecretKey[]>() {
|
||||
new PrivilegedExceptionAction<Object>() {
|
||||
@Override
|
||||
public SecretKey[] run() throws Exception {
|
||||
public Object run() throws Exception {
|
||||
// get kerberos key for the default principal
|
||||
return Krb5Helper.getServerKeys(acc);
|
||||
return Krb5Helper.getServiceCreds(acc);
|
||||
}});
|
||||
|
||||
// check permission to access and use the secret key of the
|
||||
// Kerberized "host" service
|
||||
if (kerberosKeys != null && kerberosKeys.length > 0) {
|
||||
if (serviceCreds != null) {
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
for (SecretKey k: kerberosKeys) {
|
||||
System.out.println("Using Kerberos key: " +
|
||||
k);
|
||||
System.out.println("Using Kerberos creds");
|
||||
}
|
||||
String serverPrincipal =
|
||||
Krb5Helper.getServerPrincipalName(serviceCreds);
|
||||
if (serverPrincipal != null) {
|
||||
// When service is bound, we check ASAP. Otherwise,
|
||||
// will check after client request is received
|
||||
// in in Kerberos ClientKeyExchange
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
// Eliminate dependency on ServicePermission
|
||||
sm.checkPermission(Krb5Helper.getServicePermission(
|
||||
serverPrincipal, "accept"), acc);
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
serviceCreds = null;
|
||||
// Do not destroy keys. Will affect Subject
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("Permission to access Kerberos"
|
||||
+ " secret key denied");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String serverPrincipal =
|
||||
Krb5Helper.getServerPrincipalName(kerberosKeys[0]);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
// Eliminate dependency on ServicePermission
|
||||
sm.checkPermission(Krb5Helper.getServicePermission(
|
||||
serverPrincipal, "accept"), acc);
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
kerberosKeys = null;
|
||||
// %%% destroy keys? or will that affect Subject?
|
||||
if (debug != null && Debug.isOn("handshake"))
|
||||
System.out.println("Permission to access Kerberos"
|
||||
+ " secret key denied");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (kerberosKeys != null && kerberosKeys.length > 0);
|
||||
return serviceCreds != null;
|
||||
} catch (PrivilegedActionException e) {
|
||||
// Likely exception here is LoginExceptin
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
|
||||
@ -33,8 +33,8 @@ import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.SecureRandom;
|
||||
import java.net.InetAddress;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
@ -44,18 +44,19 @@ import sun.security.jgss.GSSCaller;
|
||||
import sun.security.krb5.EncryptionKey;
|
||||
import sun.security.krb5.EncryptedData;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.Realm;
|
||||
import sun.security.krb5.internal.Ticket;
|
||||
import sun.security.krb5.internal.EncTicketPart;
|
||||
import sun.security.krb5.internal.crypto.KeyUsage;
|
||||
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.jgss.krb5.ServiceCreds;
|
||||
import sun.security.krb5.KrbException;
|
||||
import sun.security.krb5.internal.Krb5;
|
||||
|
||||
import sun.security.ssl.Debug;
|
||||
import sun.security.ssl.HandshakeInStream;
|
||||
import sun.security.ssl.HandshakeOutStream;
|
||||
import sun.security.ssl.Krb5Helper;
|
||||
import sun.security.ssl.ProtocolVersion;
|
||||
|
||||
/**
|
||||
@ -138,16 +139,15 @@ public final class KerberosClientKeyExchangeImpl
|
||||
* @param rand random number generator used for generating random
|
||||
* premaster secret if ticket and/or premaster verification fails
|
||||
* @param input inputstream from which to get ASN.1-encoded KerberosWrapper
|
||||
* @param serverKey server's master secret key
|
||||
* @param acc the AccessControlContext of the handshaker
|
||||
* @param serviceCreds server's creds
|
||||
*/
|
||||
@Override
|
||||
public void init(ProtocolVersion protocolVersion,
|
||||
ProtocolVersion clientVersion,
|
||||
SecureRandom rand, HandshakeInStream input, SecretKey[] secretKeys)
|
||||
SecureRandom rand, HandshakeInStream input, AccessControlContext acc, Object serviceCreds)
|
||||
throws IOException {
|
||||
|
||||
KerberosKey[] serverKeys = (KerberosKey[])secretKeys;
|
||||
|
||||
// Read ticket
|
||||
encodedTicket = input.getBytes16();
|
||||
|
||||
@ -163,9 +163,42 @@ public final class KerberosClientKeyExchangeImpl
|
||||
|
||||
EncryptedData encPart = t.encPart;
|
||||
PrincipalName ticketSname = t.sname;
|
||||
Realm ticketRealm = t.sname.getRealm();
|
||||
|
||||
String serverPrincipal = serverKeys[0].getPrincipal().getName();
|
||||
final ServiceCreds creds = (ServiceCreds)serviceCreds;
|
||||
final KerberosPrincipal princ =
|
||||
new KerberosPrincipal(ticketSname.toString());
|
||||
|
||||
// For bound service, permission already checked at setup
|
||||
if (creds.getName() == null) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
// Eliminate dependency on ServicePermission
|
||||
sm.checkPermission(Krb5Helper.getServicePermission(
|
||||
ticketSname.toString(), "accept"), acc);
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
serviceCreds = null;
|
||||
// Do not destroy keys. Will affect Subject
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("Permission to access Kerberos"
|
||||
+ " secret key denied");
|
||||
}
|
||||
throw new IOException("Kerberos service not allowedy");
|
||||
}
|
||||
}
|
||||
KerberosKey[] serverKeys = AccessController.doPrivileged(
|
||||
new PrivilegedAction<KerberosKey[]>() {
|
||||
@Override
|
||||
public KerberosKey[] run() {
|
||||
return creds.getKKeys(princ);
|
||||
}
|
||||
});
|
||||
if (serverKeys.length == 0) {
|
||||
throw new IOException("Found no key for " + princ +
|
||||
(creds.getName() == null ? "" :
|
||||
(", this keytab is for " + creds.getName() + " only")));
|
||||
}
|
||||
|
||||
/*
|
||||
* permission to access and use the secret key of the Kerberized
|
||||
@ -174,17 +207,6 @@ public final class KerberosClientKeyExchangeImpl
|
||||
* before promising the client
|
||||
*/
|
||||
|
||||
// Check that ticket Sname matches serverPrincipal
|
||||
String ticketPrinc = ticketSname.toString();
|
||||
if (!ticketPrinc.equals(serverPrincipal)) {
|
||||
if (debug != null && Debug.isOn("handshake"))
|
||||
System.out.println("Service principal in Ticket does not"
|
||||
+ " match associated principal in KerberosKey");
|
||||
throw new IOException("Server principal is " +
|
||||
serverPrincipal + " but ticket is for " +
|
||||
ticketPrinc);
|
||||
}
|
||||
|
||||
// See if we have the right key to decrypt the ticket to get
|
||||
// the session key.
|
||||
int encPartKeyType = encPart.getEType();
|
||||
@ -198,9 +220,8 @@ public final class KerberosClientKeyExchangeImpl
|
||||
}
|
||||
if (dkey == null) {
|
||||
// %%% Should print string repr of etype
|
||||
throw new IOException(
|
||||
"Cannot find key of appropriate type to decrypt ticket - need etype " +
|
||||
encPartKeyType);
|
||||
throw new IOException("Cannot find key of appropriate type" +
|
||||
" to decrypt ticket - need etype " + encPartKeyType);
|
||||
}
|
||||
|
||||
EncryptionKey secretKey = new EncryptionKey(
|
||||
@ -222,7 +243,7 @@ public final class KerberosClientKeyExchangeImpl
|
||||
sessionKey = encTicketPart.key;
|
||||
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("server principal: " + serverPrincipal);
|
||||
System.out.println("server principal: " + ticketSname);
|
||||
System.out.println("cname: " + encTicketPart.cname.toString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -382,12 +403,22 @@ public final class KerberosClientKeyExchangeImpl
|
||||
KerberosKey[] keys) throws KrbException {
|
||||
int ktype;
|
||||
boolean etypeFound = false;
|
||||
|
||||
// When no matched kvno is found, returns tke key of the same
|
||||
// etype with the highest kvno
|
||||
int kvno_found = 0;
|
||||
KerberosKey key_found = null;
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
ktype = keys[i].getKeyType();
|
||||
if (etype == ktype) {
|
||||
int kv = keys[i].getVersionNumber();
|
||||
etypeFound = true;
|
||||
if (versionMatches(version, keys[i].getVersionNumber())) {
|
||||
if (versionMatches(version, kv)) {
|
||||
return keys[i];
|
||||
} else if (kv > kvno_found) {
|
||||
key_found = keys[i];
|
||||
kvno_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -399,18 +430,25 @@ public final class KerberosClientKeyExchangeImpl
|
||||
ktype = keys[i].getKeyType();
|
||||
if (ktype == EncryptedData.ETYPE_DES_CBC_CRC ||
|
||||
ktype == EncryptedData.ETYPE_DES_CBC_MD5) {
|
||||
int kv = keys[i].getVersionNumber();
|
||||
etypeFound = true;
|
||||
if (versionMatches(version, keys[i].getVersionNumber())) {
|
||||
if (versionMatches(version, kv)) {
|
||||
return new KerberosKey(keys[i].getPrincipal(),
|
||||
keys[i].getEncoded(),
|
||||
etype,
|
||||
keys[i].getVersionNumber());
|
||||
kv);
|
||||
} else if (kv > kvno_found) {
|
||||
key_found = new KerberosKey(keys[i].getPrincipal(),
|
||||
keys[i].getEncoded(),
|
||||
etype,
|
||||
kv);
|
||||
kvno_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (etypeFound) {
|
||||
throw new KrbException(Krb5.KRB_AP_ERR_BADKEYVER);
|
||||
return key_found;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -28,9 +28,11 @@ package sun.security.ssl.krb5;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.Permission;
|
||||
import java.security.Principal;
|
||||
import java.util.Set;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KeyTab;
|
||||
import javax.security.auth.kerberos.ServicePermission;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
@ -61,17 +63,16 @@ public class Krb5ProxyImpl implements Krb5Proxy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKey[] getServerKeys(AccessControlContext acc)
|
||||
public Object getServiceCreds(AccessControlContext acc)
|
||||
throws LoginException {
|
||||
ServiceCreds serviceCreds =
|
||||
Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc);
|
||||
return serviceCreds != null ? serviceCreds.getKKeys() :
|
||||
new KerberosKey[0];
|
||||
return serviceCreds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerPrincipalName(SecretKey kerberosKey) {
|
||||
return ((KerberosKey)kerberosKey).getPrincipal().getName();
|
||||
public String getServerPrincipalName(Object serviceCreds) {
|
||||
return ((ServiceCreds)serviceCreds).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,4 +101,21 @@ public class Krb5ProxyImpl implements Krb5Proxy {
|
||||
String action) {
|
||||
return new ServicePermission(principalName, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRelated(Subject subject, Principal princ) {
|
||||
if (princ == null) return false;
|
||||
Set<Principal> principals =
|
||||
subject.getPrincipals(Principal.class);
|
||||
if (principals.contains(princ)) {
|
||||
// bound to this principal
|
||||
return true;
|
||||
}
|
||||
for (KeyTab pc: subject.getPrivateCredentials(KeyTab.class)) {
|
||||
if (!pc.isBound()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,10 +23,11 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6894643 6913636
|
||||
* @bug 6894643 6913636 8005523
|
||||
* @summary Test JSSE Kerberos ciphersuite
|
||||
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_RC4_128_MD5
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_SHA
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_MD5
|
||||
* @run main/othervm SSL TLS_KRB5_WITH_DES_CBC_SHA
|
||||
@ -38,14 +39,17 @@
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.Permission;
|
||||
import javax.net.ssl.*;
|
||||
import java.security.Principal;
|
||||
import java.util.Date;
|
||||
import javax.security.auth.kerberos.ServicePermission;
|
||||
import sun.security.jgss.GSSUtil;
|
||||
import sun.security.krb5.PrincipalName;
|
||||
import sun.security.krb5.internal.ktab.KeyTab;
|
||||
|
||||
public class SSL {
|
||||
public class SSL extends SecurityManager {
|
||||
|
||||
private static String krb5Cipher;
|
||||
private static final int LOOP_LIMIT = 3;
|
||||
@ -53,13 +57,32 @@ public class SSL {
|
||||
private static volatile String server;
|
||||
private static volatile int port;
|
||||
|
||||
private static String permChecks = "";
|
||||
|
||||
// 0-Not started, 1-Start OK, 2-Failure
|
||||
private static volatile int serverState = 0;
|
||||
|
||||
@Override
|
||||
public void checkPermission(Permission perm, Object context) {
|
||||
checkPermission(perm);
|
||||
}
|
||||
|
||||
public void checkPermission(Permission perm) {
|
||||
if (!(perm instanceof ServicePermission)) {
|
||||
return;
|
||||
}
|
||||
ServicePermission p = (ServicePermission)perm;
|
||||
permChecks = permChecks + p.getActions().toUpperCase().charAt(0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
krb5Cipher = args[0];
|
||||
|
||||
boolean unbound = args.length > 1;
|
||||
|
||||
System.setSecurityManager(new SSL());
|
||||
|
||||
KDC kdc = KDC.create(OneKDC.REALM);
|
||||
// Run this after KDC, so our own DNS service can be started
|
||||
try {
|
||||
@ -85,6 +108,7 @@ public class SSL {
|
||||
// and use the middle one as the real key
|
||||
kdc.addPrincipal("host/" + server, "pass2".toCharArray());
|
||||
|
||||
|
||||
// JAAS config entry name ssl
|
||||
System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF);
|
||||
File f = new File(OneKDC.JAAS_CONF);
|
||||
@ -92,7 +116,9 @@ public class SSL {
|
||||
fos.write((
|
||||
"ssl {\n" +
|
||||
" com.sun.security.auth.module.Krb5LoginModule required\n" +
|
||||
" principal=\"host/" + server + "\"\n" +
|
||||
(unbound ?
|
||||
" principal=*\n" :
|
||||
" principal=\"host/" + server + "\"\n") +
|
||||
" useKeyTab=true\n" +
|
||||
" keyTab=" + OneKDC.KTAB + "\n" +
|
||||
" isInitiator=false\n" +
|
||||
@ -103,7 +129,6 @@ public class SSL {
|
||||
Context c;
|
||||
final Context s = Context.fromJAAS("ssl");
|
||||
|
||||
// There's no keytab file when server starts.
|
||||
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
|
||||
|
||||
Thread server = new Thread(new Runnable() {
|
||||
@ -127,21 +152,6 @@ public class SSL {
|
||||
throw new Exception("Server already failed");
|
||||
}
|
||||
|
||||
// Now create the keytab
|
||||
|
||||
/*
|
||||
// Add 3 versions of keys into keytab
|
||||
KeyTab ktab = KeyTab.create(OneKDC.KTAB);
|
||||
PrincipalName service = new PrincipalName(
|
||||
"host/" + server, PrincipalName.KRB_NT_SRV_HST);
|
||||
ktab.addEntry(service, "pass1".toCharArray(), 1);
|
||||
ktab.addEntry(service, "pass2".toCharArray(), 2);
|
||||
ktab.addEntry(service, "pass3".toCharArray(), 3);
|
||||
ktab.save();
|
||||
|
||||
// and use the middle one as the real key
|
||||
kdc.addPrincipal("host/" + server, "pass2".toCharArray());
|
||||
*/
|
||||
c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
|
||||
c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
|
||||
c.doAs(new JsseClientAction(), null);
|
||||
@ -157,20 +167,22 @@ public class SSL {
|
||||
c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
|
||||
c.doAs(new JsseClientAction(), null);
|
||||
|
||||
// Revoke the old key
|
||||
/*Thread.sleep(2000);
|
||||
ktab = KeyTab.create(OneKDC.KTAB);
|
||||
ktab.addEntry(service, "pass5".toCharArray(), 5, false);
|
||||
ktab.save();
|
||||
|
||||
c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
|
||||
c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
|
||||
try {
|
||||
c.doAs(new JsseClientAction(), null);
|
||||
throw new Exception("Should fail this time.");
|
||||
} catch (SSLException e) {
|
||||
// Correct behavior.
|
||||
}*/
|
||||
// Permission checking check. Please note this is highly
|
||||
// implementation related.
|
||||
if (unbound) {
|
||||
// For unbound, server does not know what name to check.
|
||||
// Client checks "initiate", then server gets the name
|
||||
// and checks "accept". Second connection resume.
|
||||
if (!permChecks.equals("IA")) {
|
||||
throw new Exception();
|
||||
}
|
||||
} else {
|
||||
// For bound, JAAS checks "accept" once. Server checks again,
|
||||
// client then checks "initiate". Second connection resume.
|
||||
if (!permChecks.equals("AAI")) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Following codes copied from
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user