8187218: GSSCredential.getRemainingLifetime() returns negative value for TTL > 24 days
Co-authored-by: Weijun Wang <weijun.wang@oracle.com> Reviewed-by: mullan
This commit is contained in:
parent
22c9d34be1
commit
b3e5409c1d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, 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
|
||||
@ -234,14 +234,12 @@ public class Krb5InitCredential
|
||||
* @exception GSSException may be thrown
|
||||
*/
|
||||
public int getInitLifetime() throws GSSException {
|
||||
int retVal = 0;
|
||||
Date d = getEndTime();
|
||||
if (d == null) {
|
||||
return 0;
|
||||
}
|
||||
retVal = (int)(d.getTime() - (new Date().getTime()));
|
||||
|
||||
return retVal/1000;
|
||||
long retVal = d.getTime() - System.currentTimeMillis();
|
||||
return (int)(retVal/1000);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -713,10 +713,10 @@ public class KDC {
|
||||
/**
|
||||
* Returns a KerberosTime.
|
||||
*
|
||||
* @param offset offset from NOW in milliseconds
|
||||
* @param offset offset from NOW in seconds
|
||||
*/
|
||||
private static KerberosTime timeFor(long offset) {
|
||||
return new KerberosTime(new Date().getTime() + offset);
|
||||
private static KerberosTime timeAfter(int offset) {
|
||||
return new KerberosTime(new Date().getTime() + offset * 1000L);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -832,12 +832,12 @@ public class KDC {
|
||||
KerberosTime from = body.from;
|
||||
KerberosTime till = body.till;
|
||||
if (from == null || from.isZero()) {
|
||||
from = timeFor(0);
|
||||
from = timeAfter(0);
|
||||
}
|
||||
if (till == null) {
|
||||
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
|
||||
} else if (till.isZero()) {
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
till = timeAfter(DEFAULT_LIFETIME);
|
||||
}
|
||||
|
||||
boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
@ -863,7 +863,7 @@ public class KDC {
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
|
||||
//renew = timeFor(1000 * 3600 * 24 * 7);
|
||||
//renew = timeAfter(3600 * 24 * 7);
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
|
||||
@ -933,7 +933,7 @@ public class KDC {
|
||||
key,
|
||||
cname,
|
||||
new TransitedEncoding(1, new byte[0]), // TODO
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
from,
|
||||
till, renewTill,
|
||||
body.addresses != null ? body.addresses
|
||||
@ -952,13 +952,13 @@ public class KDC {
|
||||
EncTGSRepPart enc_part = new EncTGSRepPart(
|
||||
key,
|
||||
new LastReq(new LastReqEntry[] {
|
||||
new LastReqEntry(0, timeFor(-10000))
|
||||
new LastReqEntry(0, timeAfter(-10))
|
||||
}),
|
||||
body.getNonce(), // TODO: detect replay
|
||||
timeFor(1000 * 3600 * 24),
|
||||
timeAfter(3600 * 24),
|
||||
// Next 5 and last MUST be same with ticket
|
||||
tFlags,
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
from,
|
||||
till, renewTill,
|
||||
service,
|
||||
@ -986,7 +986,7 @@ public class KDC {
|
||||
+ " " +ke.returnCodeMessage());
|
||||
if (kerr == null) {
|
||||
kerr = new KRBError(null, null, null,
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
0,
|
||||
ke.returnCode(),
|
||||
body.cname,
|
||||
@ -1059,20 +1059,21 @@ public class KDC {
|
||||
KerberosTime till = body.till;
|
||||
KerberosTime rtime = body.rtime;
|
||||
if (from == null || from.isZero()) {
|
||||
from = timeFor(0);
|
||||
from = timeAfter(0);
|
||||
}
|
||||
if (till == null) {
|
||||
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
|
||||
} else if (till.isZero()) {
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
} else if (till.greaterThan(timeFor(24 * 3600 * 1000))) {
|
||||
till = timeAfter(DEFAULT_LIFETIME);
|
||||
} else if (till.greaterThan(timeAfter(24 * 3600))
|
||||
&& System.getProperty("test.kdc.force.till") == null) {
|
||||
// If till is more than 1 day later, make it renewable
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
till = timeAfter(DEFAULT_LIFETIME);
|
||||
body.kdcOptions.set(KDCOptions.RENEWABLE, true);
|
||||
if (rtime == null) rtime = till;
|
||||
}
|
||||
if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
rtime = timeFor(1000 * DEFAULT_RENEWTIME);
|
||||
rtime = timeAfter(DEFAULT_RENEWTIME);
|
||||
}
|
||||
//body.from
|
||||
boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
@ -1088,7 +1089,7 @@ public class KDC {
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
|
||||
//renew = timeFor(1000 * 3600 * 24 * 7);
|
||||
//renew = timeAfter(3600 * 24 * 7);
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
|
||||
@ -1234,7 +1235,7 @@ public class KDC {
|
||||
key,
|
||||
body.cname,
|
||||
new TransitedEncoding(1, new byte[0]),
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
from,
|
||||
till, rtime,
|
||||
body.addresses,
|
||||
@ -1246,13 +1247,13 @@ public class KDC {
|
||||
EncASRepPart enc_part = new EncASRepPart(
|
||||
key,
|
||||
new LastReq(new LastReqEntry[]{
|
||||
new LastReqEntry(0, timeFor(-10000))
|
||||
new LastReqEntry(0, timeAfter(-10))
|
||||
}),
|
||||
body.getNonce(), // TODO: detect replay?
|
||||
timeFor(1000 * 3600 * 24),
|
||||
timeAfter(3600 * 24),
|
||||
// Next 5 and last MUST be same with ticket
|
||||
tFlags,
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
from,
|
||||
till, rtime,
|
||||
service,
|
||||
@ -1314,7 +1315,7 @@ public class KDC {
|
||||
eData = temp.toByteArray();
|
||||
}
|
||||
kerr = new KRBError(null, null, null,
|
||||
timeFor(0),
|
||||
timeAfter(0),
|
||||
0,
|
||||
ke.returnCode(),
|
||||
body.cname,
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8131051 8194486
|
||||
* @bug 8131051 8194486 8187218
|
||||
* @summary KDC might issue a renewable ticket even if not requested
|
||||
* @library /test/lib
|
||||
* @compile -XDignore.symbol.file LongLife.java
|
||||
@ -31,7 +31,12 @@
|
||||
* @run main/othervm -Djdk.net.hosts.file=TestHosts LongLife
|
||||
*/
|
||||
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import sun.security.krb5.Config;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
public class LongLife {
|
||||
|
||||
@ -39,11 +44,53 @@ public class LongLife {
|
||||
|
||||
OneKDC kdc = new OneKDC(null).writeJAASConf();
|
||||
|
||||
// A lifetime 2d will make it renewable
|
||||
test(kdc, "10h", false, 36000, false);
|
||||
test(kdc, "2d", false, KDC.DEFAULT_LIFETIME, true);
|
||||
test(kdc, "2d", true, 2 * 24 * 3600, false);
|
||||
|
||||
// 8187218: getRemainingLifetime() is negative if lifetime
|
||||
// is longer than 30 days.
|
||||
test(kdc, "30d", true, 30 * 24 * 3600, false);
|
||||
}
|
||||
|
||||
static void test(
|
||||
KDC kdc,
|
||||
String ticketLifetime,
|
||||
boolean forceTill, // if true, KDC will not try RENEWABLE
|
||||
int expectedLifeTime,
|
||||
boolean expectedRenewable) throws Exception {
|
||||
|
||||
KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
|
||||
"ticket_lifetime = 2d");
|
||||
"ticket_lifetime = " + ticketLifetime);
|
||||
Config.refresh();
|
||||
|
||||
Context.fromJAAS("client");
|
||||
if (forceTill) {
|
||||
System.setProperty("test.kdc.force.till", "");
|
||||
} else {
|
||||
System.clearProperty("test.kdc.force.till");
|
||||
}
|
||||
|
||||
Context c = Context.fromJAAS("client");
|
||||
|
||||
GSSCredential cred = Subject.doAs(c.s(),
|
||||
(PrivilegedExceptionAction<GSSCredential>)
|
||||
()-> {
|
||||
GSSManager m = GSSManager.getInstance();
|
||||
return m.createCredential(GSSCredential.INITIATE_ONLY);
|
||||
});
|
||||
|
||||
KerberosTicket tgt = c.s().getPrivateCredentials(KerberosTicket.class)
|
||||
.iterator().next();
|
||||
System.out.println(tgt);
|
||||
|
||||
int actualLifeTime = cred.getRemainingLifetime();
|
||||
if (actualLifeTime < expectedLifeTime - 60
|
||||
|| actualLifeTime > expectedLifeTime + 60) {
|
||||
throw new Exception("actualLifeTime is " + actualLifeTime);
|
||||
}
|
||||
|
||||
if (tgt.isRenewable() != expectedRenewable) {
|
||||
throw new Exception("TGT's RENEWABLE flag is " + tgt.isRenewable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user