Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8058290

JAAS Krb5LoginModule has suspect ticket-renewal logic, relies on clockskew grace

    XMLWordPrintable

Details

    • b74
    • Verified

    Backports

      Description

        In Krb5LoginModule, when using the native ticket cache (useTicketCache=true)
        with the renewal option enabled (renewTGT=true), the module will attempt to
        renew a renewable TGT. The method Krb5LoginModule#isCurrent(...) is used to
        decide whether to trigger the renewal request (renewTGT=true) or ignore that
        ticket (with a debug message) and proceed with other authentication options
        when (renewTGT=false).

        The check in isCurrent() is correct according to its name - it checks whether
        the ticket has expired or not, that is, whether our current time is beyond
        the ticket end time:

            private boolean isCurrent(Credentials creds)
            {
                Date endTime = creds.getEndTime();
                if (endTime != null) {
                    return (System.currentTimeMillis() <= endTime.getTime());
                }
                return true;
            }

        However, according to RFC4120 [1] "The Kerberos Network Authentication
        Service (V5)", section 2.3 "Renewable Tickets":

        <rfc1420>
        Renewable tickets have two "expiration times": the first is when the current
        instance of the ticket expires, and the second is the latest permissible
        value for an individual expiration time. An application client must
        periodically (i.e., before it expires) present a renewable ticket to the KDC,
        with the RENEW option set in the KDC request.
        </rfc1420>

        That is, expired tickets cannot be renewed, regardless of the renewable
        period. A ticket is renewable provided that we are within its (fixed)
        renewable period, AND the ticket has not already expired. For example, a TGT
        may be issued with validity from now and an expiry 24 hours hence, and with a
        renewable period of 30 days. The ticket can be renewed each day for 30 days,
        but it must be renewed at least once per day, otherwise it will expire.
        Expired tickets cannot be renewed. See also the comment for "kinit -R":

        -R requests renewal of the ticket-granting ticket. Note that an expired
        ticket cannot be renewed, even if the ticket is still within its renewable
        life.

        The above logic would appear to be oblivious to this logic (it does not
        attempt to renew until it thinks the ticket has expired), and therefore
        should never work, or very rarely at best when renewed at exactly the right
        time, and you would think that this would be an easily spotted problem. In
        fact ticket-renewal will succeed for a period after the ticket expires, due
        to client/KDC allowances for clock-skew, as configured in krb5.conf variable
        "clockskew", which defaults to 300 (seconds, or 5 minutes). So someone
        testing this code, who attempts to renew a ticket-cache ticket that has
        technically expired (but recently), will see it renew successfully due to
        clock-skew allowances.
        .
        This logic is problematic for the following reasons, as we rely on the
        clockskew setting (which we don't control and is not visible) for a grace
        period to renew an otherwise already expired ticket (which is not normally
        allowed). In the above example, we have a 24 hour period each day in the
        month to renew the TGT, but we rely on whatever clockskew is set (default 5
        minutes), so the success window for this is reduced to that period.
        .
        The correct logic would be to divide the ticket-lifetime (endTime -
        startTime), multiply it by a (fixed?) renew threshold, say half-way or 0.5
        (after 12h per example), and then compare the currentTimeMillis() to that
        time, and if we are more than half-way expired, trigger the renewal. This is
        a standard Kerberos approach to deal with issues such as KDC outages or
        infrequent inspection of the current TGT (idle application sessions).

        [1] http://www.ietf.org/rfc/rfc4120.txt
                                                

        Attachments

          Issue Links

            Activity

              People

                weijun Weijun Wang
                shadowbug Shadow Bug
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: