提交 5c5ada47 编写于 作者: W weijun

6959292: regression: cannot login if session key and preauth does not use the same etype

Reviewed-by: xuelei, valeriep
上级 1a922368
......@@ -356,7 +356,6 @@ public class Credentials {
* @param princ the client principal. This value cannot be null.
* @param secretKey the secret key of the client principal.This value
* cannot be null.
* @param password if null, caller is using a keytab
* @returns the TGT credentials
*/
public static Credentials acquireTGT(PrincipalName princ,
......@@ -373,18 +372,8 @@ public class Credentials {
"Cannot have null secretKey to do AS-Exchange");
KrbAsRep asRep = null;
// The etype field to be placed in AS-REQ. If caller is using keytab,
// it must be limited to etypes in keytab. Otherwise, leave it null,
// and KrbAsReq will populate it with all supported etypes.
int[] eTypes = null;
if (password == null) {
eTypes = EncryptionKey.getETypes(secretKeys);
}
try {
asRep = sendASRequest(princ, secretKeys, eTypes, null);
asRep = sendASRequest(princ, secretKeys, null);
} catch (KrbException ke) {
if ((ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) ||
(ke.returnCode() == Krb5.KDC_ERR_PREAUTH_REQUIRED)) {
......@@ -407,7 +396,7 @@ public class Credentials {
princ.getSalt(), true,
error.getEType(), error.getParams());
}
asRep = sendASRequest(princ, secretKeys, eTypes, ke.getError());
asRep = sendASRequest(princ, secretKeys, ke.getError());
} else {
throw ke;
}
......@@ -417,18 +406,17 @@ public class Credentials {
/**
* Sends the AS-REQ
* @param eTypes not null if caller using keytab
*/
private static KrbAsRep sendASRequest(PrincipalName princ,
EncryptionKey[] secretKeys, int[] eTypes, KRBError error)
EncryptionKey[] secretKeys, KRBError error)
throws KrbException, IOException {
// %%%
KrbAsReq asReq = null;
if (error == null) {
asReq = new KrbAsReq(princ, secretKeys, eTypes);
asReq = new KrbAsReq(princ, secretKeys);
} else {
asReq = new KrbAsReq(princ, secretKeys, eTypes, true,
asReq = new KrbAsReq(princ, secretKeys, true,
error.getEType(), error.getSalt(), error.getParams());
}
......
......@@ -76,26 +76,6 @@ public class EncryptionKey
private static final boolean DEBUG = Krb5.DEBUG;
public static int[] getETypes(EncryptionKey[] keys) {
int len = keys.length;
int[] result = new int[len];
int count = 0; // Number of elements in result. Might be less than
// len if there are keys having the same etype
loopi: for (int i=0; i<len; i++) {
int eType = keys[i].getEType();
for (int j=0; j<count; j++) {
if (result[j] == eType) {
continue loopi;
}
}
result[count++] = eType;
}
if (count != len) {
result = Arrays.copyOf(result, count);
}
return result;
}
public synchronized int getEType() {
return keyType;
}
......@@ -208,24 +188,13 @@ public class EncryptionKey
etypes = EType.getBuiltInDefaults();
}
// set the preferred etype for preauth
if ((pa_exists) && (pa_etype != EncryptedData.ETYPE_NULL)) {
if (DEBUG) {
System.out.println("Pre-Authentication: " +
"Set preferred etype = " + pa_etype);
}
if (EType.isSupported(pa_etype)) {
// reset etypes to preferred value
etypes = new int[1];
etypes[0] = pa_etype;
}
}
EncryptionKey[] encKeys = new EncryptionKey[etypes.length];
for (int i = 0; i < etypes.length; i++) {
if (EType.isSupported(etypes[i])) {
byte[] s2kparams = (pa_exists && etypes[i] == pa_etype)
? pa_s2kparams : null;
encKeys[i] = new EncryptionKey(
stringToKey(password, salt, pa_s2kparams, etypes[i]),
stringToKey(password, salt, s2kparams, etypes[i]),
etypes[i], null);
} else {
if (DEBUG) {
......
......@@ -35,9 +35,11 @@ import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.crypto.Nonce;
import sun.security.krb5.internal.crypto.KeyUsage;
import sun.security.util.*;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.StringTokenizer;
/**
* This class encapsulates the KRB-AS-REQ message that the client
......@@ -62,13 +64,11 @@ public class KrbAsReq extends KrbKdcReq {
/**
* Creates a KRB-AS-REQ to send to the default KDC
* @param eTypes not null when using a keytab, this can make sure the etypes
* in AS-REQ contains only those available on client
* @throws KrbException
* @throws IOException
*/
// Called by Credentials
KrbAsReq(PrincipalName principal, EncryptionKey[] keys, int[] eTypes)
KrbAsReq(PrincipalName principal, EncryptionKey[] keys)
throws KrbException, IOException {
this(keys, // for pre-authentication
false, 0, null, null, // pre-auth values
......@@ -78,7 +78,7 @@ public class KrbAsReq extends KrbKdcReq {
null, // KerberosTime from
null, // KerberosTime till
null, // KerberosTime rtime
eTypes, // int[] eTypes
null, // int[] eTypes
null, // HostAddresses addresses
null); // Ticket[] additionalTickets
}
......@@ -86,10 +86,8 @@ public class KrbAsReq extends KrbKdcReq {
/**
* Creates a KRB-AS-REQ to send to the default KDC
* with pre-authentication values
* @param eTypes not null when using a keytab, this can make sure the etypes
* in AS-REQ contains only those available on client
*/
KrbAsReq(PrincipalName principal, EncryptionKey[] keys, int[] eTypes,
KrbAsReq(PrincipalName principal, EncryptionKey[] keys,
boolean pa_exists, int etype, String salt, byte[] s2kparams)
throws KrbException, IOException {
this(keys, // for pre-authentication
......@@ -100,7 +98,7 @@ public class KrbAsReq extends KrbKdcReq {
null, // KerberosTime from
null, // KerberosTime till
null, // KerberosTime rtime
eTypes, // int[] eTypes
null, // int[] eTypes
null, // HostAddresses addresses
null); // Ticket[] additionalTickets
}
......@@ -344,24 +342,18 @@ public class KrbAsReq extends KrbKdcReq {
}
princName = cname;
// keys might contain many etypes, or only one if in preauth mode,
// coz EncryptionKey.acquireSecretKeys() with pa returns only one key.
int[] tktETypes = EType.getDefaults("default_tkt_enctypes", keys);
PAData[] paData = null;
if (PA_ENC_TIMESTAMP_REQUIRED) {
EncryptionKey key = null;
if (pa_etype != EncryptedData.ETYPE_NULL) {
if (DEBUG) {
System.out.println("Pre-Authenticaton: " +
"find key for etype = " + pa_etype);
System.out.println("Pre-Authenticaton: find key for etype = " + pa_etype);
}
key = EncryptionKey.findKey(pa_etype, keys);
} else {
int[] availableETypes =
EType.getDefaults("default_tkt_enctypes", keys);
if (availableETypes.length > 0) {
key = EncryptionKey.findKey(availableETypes[0], keys);
if (tktETypes.length > 0) {
key = EncryptionKey.findKey(tktETypes[0], keys);
}
}
if (DEBUG) {
......@@ -384,7 +376,7 @@ public class KrbAsReq extends KrbKdcReq {
}
if (eTypes == null) {
eTypes = EType.getDefaults("default_tkt_enctypes");
eTypes = tktETypes;
}
// check to use addresses in tickets
......
......@@ -286,6 +286,19 @@ public class KRBError implements java.io.Serializable {
salt = info.getSalt();
if (DEBUG) {
System.out.println("\t PA-ETYPE-INFO etype = " + etype);
System.out.println("\t PA-ETYPE-INFO salt = " + salt);
}
while (der.data.available() > 0) {
value = der.data.getDerValue();
info = new ETypeInfo(value);
if (DEBUG) {
etype = info.getEType();
System.out.println("\t salt for " + etype
+ " is " + info.getSalt());
}
if (salt == null || salt.isEmpty()) {
salt = info.getSalt();
}
}
}
break;
......@@ -299,6 +312,19 @@ public class KRBError implements java.io.Serializable {
s2kparams = info2.getParams();
if (DEBUG) {
System.out.println("\t PA-ETYPE-INFO2 etype = " + etype);
System.out.println("\t PA-ETYPE-INFO salt = " + salt);
}
while (der.data.available() > 0) {
value = der.data.getDerValue();
info2 = new ETypeInfo2(value);
if (DEBUG) {
etype = info2.getEType();
System.out.println("\t salt for " + etype
+ " is " + info2.getSalt());
}
if (salt == null || salt.isEmpty()) {
salt = info2.getSalt();
}
}
}
break;
......
......@@ -229,9 +229,7 @@ public class Kinit {
if (useKeytab) {
as_req = new KrbAsReq(skeys, opt,
principal, sname,
null, null, null,
EncryptionKey.getETypes(skeys),
addresses, null);
null, null, null, null, addresses, null);
} else {
as_req = new KrbAsReq(psswd, opt,
principal, sname,
......@@ -259,9 +257,7 @@ public class Kinit {
if (useKeytab) {
as_req = new KrbAsReq(skeys, true, etype, salt,
s2kparams, opt, principal, sname,
null, null, null,
EncryptionKey.getETypes(skeys),
addresses, null);
null, null, null, null, addresses, null);
} else {
as_req = new KrbAsReq(psswd, true, etype, salt,
s2kparams, opt, principal, sname,
......
......@@ -155,9 +155,13 @@ public class KDC {
*/
PREAUTH_REQUIRED,
/**
* Onlyy issue TGT in RC4
* Only issue TGT in RC4
*/
ONLY_RC4_TGT,
/**
* Only use RC4 in preauth, enc-type still using eTypes[0]
*/
ONLY_RC4_PREAUTH,
};
static {
......@@ -905,7 +909,11 @@ public class KDC {
ke.returnCode() == Krb5.KDC_ERR_PREAUTH_FAILED) {
PAData pa;
ETypeInfo2 ei2 = new ETypeInfo2(eTypes[0], null, null);
int epa = eTypes[0];
if (options.containsKey(KDC.Option.ONLY_RC4_PREAUTH)) {
epa = EncryptedData.ETYPE_ARCFOUR_HMAC;
}
ETypeInfo2 ei2 = new ETypeInfo2(epa, null, null);
DerOutputStream eid = new DerOutputStream();
eid.write(DerValue.tag_Sequence, ei2.asn1Encode());
......@@ -924,7 +932,7 @@ public class KDC {
}
}
if (allOld) {
ETypeInfo ei = new ETypeInfo(eTypes[0], null);
ETypeInfo ei = new ETypeInfo(epa, null);
eid = new DerOutputStream();
eid.write(DerValue.tag_Sequence, ei.asn1Encode());
pa = new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray());
......
......@@ -23,8 +23,9 @@
/*
* @test
* @bug 6951366
* @bug 6932525 6951366 6959292
* @summary kerberos login failure on win2008 with AD set to win2000 compat mode
* and cannot login if session key and preauth does not use the same etype
*/
import com.sun.security.auth.module.Krb5LoginModule;
import java.io.File;
......@@ -52,8 +53,6 @@ public class W83 {
new File(OneKDC.KRB5_CONF).deleteOnExit();
new File(OneKDC.KTAB).deleteOnExit();
kdc.setOption(KDC.Option.ONLY_RC4_TGT, true);
KeyTab ktab = KeyTab.getInstance(OneKDC.KTAB);
for (int etype: EType.getBuiltInDefaults()) {
if (etype != EncryptedData.ETYPE_ARCFOUR_HMAC) {
......@@ -61,6 +60,15 @@ public class W83 {
}
}
ktab.save();
// For 6932525 and 6951366, make sure the etypes sent in 2nd AS-REQ
// is not restricted to that of preauth
kdc.setOption(KDC.Option.ONLY_RC4_TGT, true);
x.go();
// For 6959292, make sure that when etype for enc-part in 2nd AS-REQ
// is different from that of preauth, client can still decrypt it
kdc.setOption(KDC.Option.ONLY_RC4_PREAUTH, true);
x.go();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册