Search in sources :

Example 1 with KerberosTicket

use of javax.security.auth.kerberos.KerberosTicket in project hadoop by apache.

the class UserGroupInformation method checkTGTAndReloginFromKeytab.

/**
   * Re-login a user from keytab if TGT is expired or is close to expiry.
   * 
   * @throws IOException
   * @throws KerberosAuthException if it's a kerberos login exception.
   */
public synchronized void checkTGTAndReloginFromKeytab() throws IOException {
    if (!isSecurityEnabled() || user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS || !isKeytab) {
        return;
    }
    KerberosTicket tgt = getTGT();
    if (tgt != null && !shouldRenewImmediatelyForTests && Time.now() < getRefreshTime(tgt)) {
        return;
    }
    reloginFromKeytab();
}
Also used : KerberosTicket(javax.security.auth.kerberos.KerberosTicket)

Example 2 with KerberosTicket

use of javax.security.auth.kerberos.KerberosTicket in project kafka by apache.

the class KerberosLogin method login.

/**
     * Performs login for each login module specified for the login context of this instance and starts the thread used
     * to periodically re-login to the Kerberos Ticket Granting Server.
     */
@Override
public LoginContext login() throws LoginException {
    this.lastLogin = currentElapsedTime();
    loginContext = super.login();
    subject = loginContext.getSubject();
    isKrbTicket = !subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
    List<AppConfigurationEntry> entries = jaasContext().configurationEntries();
    if (entries.isEmpty()) {
        isUsingTicketCache = false;
        principal = null;
    } else {
        // there will only be a single entry
        AppConfigurationEntry entry = entries.get(0);
        if (entry.getOptions().get("useTicketCache") != null) {
            String val = (String) entry.getOptions().get("useTicketCache");
            isUsingTicketCache = val.equals("true");
        } else
            isUsingTicketCache = false;
        if (entry.getOptions().get("principal") != null)
            principal = (String) entry.getOptions().get("principal");
        else
            principal = null;
    }
    if (!isKrbTicket) {
        log.debug("[Principal={}]: It is not a Kerberos ticket", principal);
        t = null;
        // if no TGT, do not bother with ticket management.
        return loginContext;
    }
    log.debug("[Principal={}]: It is a Kerberos ticket", principal);
    // Refresh the Ticket Granting Ticket (TGT) periodically. How often to refresh is determined by the
    // TGT's existing expiry date and the configured minTimeBeforeRelogin. For testing and development,
    // you can decrease the interval of expiration of tickets (for example, to 3 minutes) by running:
    //  "modprinc -maxlife 3mins <principal>" in kadmin.
    t = Utils.newThread(String.format("kafka-kerberos-refresh-thread-%s", principal), new Runnable() {

        public void run() {
            log.info("[Principal={}]: TGT refresh thread started.", principal);
            while (true) {
                // renewal thread's main loop. if it exits from here, thread will exit.
                KerberosTicket tgt = getTGT();
                long now = currentWallTime();
                long nextRefresh;
                Date nextRefreshDate;
                if (tgt == null) {
                    nextRefresh = now + minTimeBeforeRelogin;
                    nextRefreshDate = new Date(nextRefresh);
                    log.warn("[Principal={}]: No TGT found: will try again at {}", principal, nextRefreshDate);
                } else {
                    nextRefresh = getRefreshTime(tgt);
                    long expiry = tgt.getEndTime().getTime();
                    Date expiryDate = new Date(expiry);
                    if (isUsingTicketCache && tgt.getRenewTill() != null && tgt.getRenewTill().getTime() < expiry) {
                        log.warn("The TGT cannot be renewed beyond the next expiry date: {}." + "This process will not be able to authenticate new SASL connections after that " + "time (for example, it will not be able to authenticate a new connection with a Kafka " + "Broker).  Ask your system administrator to either increase the " + "'renew until' time by doing : 'modprinc -maxrenewlife {} ' within " + "kadmin, or instead, to generate a keytab for {}. Because the TGT's " + "expiry cannot be further extended by refreshing, exiting refresh thread now.", expiryDate, principal, principal);
                        return;
                    }
                    // would cause ticket expiration.
                    if ((nextRefresh > expiry) || (now + minTimeBeforeRelogin > expiry)) {
                        // expiry is before next scheduled refresh).
                        log.info("[Principal={}]: Refreshing now because expiry is before next scheduled refresh time.", principal);
                        nextRefresh = now;
                    } else {
                        if (nextRefresh < (now + minTimeBeforeRelogin)) {
                            // next scheduled refresh is sooner than (now + MIN_TIME_BEFORE_LOGIN).
                            Date until = new Date(nextRefresh);
                            Date newUntil = new Date(now + minTimeBeforeRelogin);
                            log.warn("[Principal={}]: TGT refresh thread time adjusted from {} to {} since the former is sooner " + "than the minimum refresh interval ({} seconds) from now.", principal, until, newUntil, minTimeBeforeRelogin / 1000);
                        }
                        nextRefresh = Math.max(nextRefresh, now + minTimeBeforeRelogin);
                    }
                    nextRefreshDate = new Date(nextRefresh);
                    if (nextRefresh > expiry) {
                        log.error("[Principal={}]: Next refresh: {} is later than expiry {}. This may indicate a clock skew problem." + "Check that this host and the KDC hosts' clocks are in sync. Exiting refresh thread.", principal, nextRefreshDate, expiryDate);
                        return;
                    }
                }
                if (now < nextRefresh) {
                    Date until = new Date(nextRefresh);
                    log.info("[Principal={}]: TGT refresh sleeping until: {}", principal, until);
                    try {
                        Thread.sleep(nextRefresh - now);
                    } catch (InterruptedException ie) {
                        log.warn("[Principal={}]: TGT renewal thread has been interrupted and will exit.", principal);
                        return;
                    }
                } else {
                    log.error("[Principal={}]: NextRefresh: {} is in the past: exiting refresh thread. Check" + " clock sync between this host and KDC - (KDC's clock is likely ahead of this host)." + " Manual intervention will be required for this client to successfully authenticate." + " Exiting refresh thread.", principal, nextRefreshDate);
                    return;
                }
                if (isUsingTicketCache) {
                    String kinitArgs = "-R";
                    int retry = 1;
                    while (retry >= 0) {
                        try {
                            log.debug("[Principal={}]: Running ticket cache refresh command: {} {}", principal, kinitCmd, kinitArgs);
                            Shell.execCommand(kinitCmd, kinitArgs);
                            break;
                        } catch (Exception e) {
                            if (retry > 0) {
                                --retry;
                                // sleep for 10 seconds
                                try {
                                    Thread.sleep(10 * 1000);
                                } catch (InterruptedException ie) {
                                    log.error("[Principal={}]: Interrupted while renewing TGT, exiting Login thread", principal);
                                    return;
                                }
                            } else {
                                log.warn("[Principal={}]: Could not renew TGT due to problem running shell command: '{} {}'; " + "exception was: %s. Exiting refresh thread.", principal, kinitCmd, kinitArgs, e, e);
                                return;
                            }
                        }
                    }
                }
                try {
                    int retry = 1;
                    while (retry >= 0) {
                        try {
                            reLogin();
                            break;
                        } catch (LoginException le) {
                            if (retry > 0) {
                                --retry;
                                // sleep for 10 seconds.
                                try {
                                    Thread.sleep(10 * 1000);
                                } catch (InterruptedException e) {
                                    log.error("[Principal={}]: Interrupted during login retry after LoginException:", principal, le);
                                    throw le;
                                }
                            } else {
                                log.error("[Principal={}]: Could not refresh TGT.", principal, le);
                            }
                        }
                    }
                } catch (LoginException le) {
                    log.error("[Principal={}]: Failed to refresh TGT: refresh thread exiting now.", principal, le);
                    return;
                }
            }
        }
    }, true);
    t.start();
    return loginContext;
}
Also used : AppConfigurationEntry(javax.security.auth.login.AppConfigurationEntry) KerberosTicket(javax.security.auth.kerberos.KerberosTicket) LoginException(javax.security.auth.login.LoginException) Date(java.util.Date) LoginException(javax.security.auth.login.LoginException)

Example 3 with KerberosTicket

use of javax.security.auth.kerberos.KerberosTicket in project storm by apache.

the class AutoTGT method renew.

@Override
public void renew(Map<String, String> credentials, Map topologyConf) {
    KerberosTicket tgt = getTGT(credentials);
    if (tgt != null) {
        long refreshTime = getRefreshTime(tgt);
        long now = System.currentTimeMillis();
        if (now >= refreshTime) {
            try {
                LOG.info("Renewing TGT for " + tgt.getClient());
                tgt.refresh();
                saveTGT(tgt, credentials);
            } catch (RefreshFailedException e) {
                LOG.warn("Failed to refresh TGT", e);
            }
        }
    }
}
Also used : KerberosTicket(javax.security.auth.kerberos.KerberosTicket) RefreshFailedException(javax.security.auth.RefreshFailedException)

Example 4 with KerberosTicket

use of javax.security.auth.kerberos.KerberosTicket in project zookeeper by apache.

the class Login method getTGT.

private synchronized KerberosTicket getTGT() {
    Set<KerberosTicket> tickets = subject.getPrivateCredentials(KerberosTicket.class);
    for (KerberosTicket ticket : tickets) {
        KerberosPrincipal server = ticket.getServer();
        if (server.getName().equals("krbtgt/" + server.getRealm() + "@" + server.getRealm())) {
            LOG.debug("Client principal is \"" + ticket.getClient().getName() + "\".");
            LOG.debug("Server principal is \"" + ticket.getServer().getName() + "\".");
            return ticket;
        }
    }
    return null;
}
Also used : KerberosPrincipal(javax.security.auth.kerberos.KerberosPrincipal) KerberosTicket(javax.security.auth.kerberos.KerberosTicket)

Example 5 with KerberosTicket

use of javax.security.auth.kerberos.KerberosTicket in project jstorm by alibaba.

the class AutoTGT method getTGT.

public static KerberosTicket getTGT(Map<String, String> credentials) {
    KerberosTicket ret = null;
    if (credentials != null && credentials.containsKey("TGT")) {
        try {
            ByteArrayInputStream bin = new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(credentials.get("TGT")));
            ObjectInputStream in = new ObjectInputStream(bin);
            ret = (KerberosTicket) in.readObject();
            in.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    return ret;
}
Also used : KerberosTicket(javax.security.auth.kerberos.KerberosTicket) ByteArrayInputStream(java.io.ByteArrayInputStream) LoginException(javax.security.auth.login.LoginException) DestroyFailedException(javax.security.auth.DestroyFailedException) RefreshFailedException(javax.security.auth.RefreshFailedException) ObjectInputStream(java.io.ObjectInputStream)

Aggregations

KerberosTicket (javax.security.auth.kerberos.KerberosTicket)35 Subject (javax.security.auth.Subject)13 Principal (java.security.Principal)7 KerberosPrincipal (javax.security.auth.kerberos.KerberosPrincipal)7 Test (org.junit.Test)7 DestroyFailedException (javax.security.auth.DestroyFailedException)6 RefreshFailedException (javax.security.auth.RefreshFailedException)6 LoginException (javax.security.auth.login.LoginException)6 HashMap (java.util.HashMap)4 LoginContext (javax.security.auth.login.LoginContext)4 IOException (java.io.IOException)3 Date (java.util.Date)3 KerberosKey (javax.security.auth.kerberos.KerberosKey)3 AbstractKerberosITest (org.apache.directory.server.kerberos.kdc.AbstractKerberosITest)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ObjectInputStream (java.io.ObjectInputStream)2 InetAddress (java.net.InetAddress)2 PrivilegedActionException (java.security.PrivilegedActionException)2 Map (java.util.Map)2 Configuration (javax.security.auth.login.Configuration)2