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:
Prasadrao Koppula 2018-03-20 11:16:10 +05:30
parent 22c9d34be1
commit b3e5409c1d
3 changed files with 77 additions and 31 deletions

View File

@ -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);
}
/**

View File

@ -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,

View File

@ -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());
}
}
}