All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jcifs.smb.Kerb5Authenticator Maven / Gradle / Ivy

Go to download

JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java

There is a newer version: 1.3.18.1
Show newest version
package jcifs.smb;

import java.security.Key;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Iterator;
import java.util.Set;

import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;

import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;

import jcifs.Config;
import jcifs.smb.ServerMessageBlock;
import jcifs.smb.Kerb5SessionSetupAndX;
import jcifs.smb.SmbException;
import jcifs.smb.SmbSession;

// >>SmbAuthenticator
/**
 * This class implements SmbExtendedAuthenticator interface to provide Kerberos
 * authentication feature. 
 * 
 * @author Shun
 *
 */
public class Kerb5Authenticator implements SmbExtendedAuthenticator{
    /**
     * This variable represents the FLAGS2 field in SMB Header block. The value
     * is predefined to support KerberosV5 authentication. In order to use 
     * KerberosV5 authentication, user need to set the Config property
     * "jcifs.smb.client.flags2" as this value. For example: 
     * 
     * Config.setProperty("jcifs.smb.client.flags2",Kerb5Authenticator.FLAGS2);
     * 
*/ public static final String FLAGS2 = "" + 0xd805; /** * This variable represents the CAPABILITIES field in SMB_PARAMETERS block. * The value is predefined to support KerberosV5 authentication. In order * to use KerberosV5 authentication, user need to set the Config * property "jcifs.smb.client.capabilities" as this value. For example: *
     * Config.setProperty("jcifs.smb.client.capabilities",Kerb5Authenticator.CAPABILITIES);
     * 
*/ public static final String CAPABILITIES = "" + 0x800000d4; private static final String SERVICE = "cifs"; private Subject subject = null; private String user = null; private String service = SERVICE; private int userLifetime = GSSCredential.DEFAULT_LIFETIME; private int contextLifetime = GSSContext.DEFAULT_LIFETIME; /** * Contruct a Kerb5Authenticator object with Subject * which hold TGT retrieved from KDC. If multiple TGT are contained, the * first one will be used to retrieve user principal. * * @param subject represents the user who perform Kerberos authentication. * It contains tickets retrieve from KDC. */ public Kerb5Authenticator(Subject subject){ this.subject = subject; } /** * Set the user name which is used to setup GSSContext. If null * is set, the default user will be used which is retrieved from the first * TGT found in Subject . * * @param name the user name used to setup GSSContext */ public void setUser(String name){ user = name; } /** * Get the Subject object. * * @return Subject represents the user who perform Kerberos authentication. * It contains the tickets retrieve from KDC. */ public Subject getSubject() { return subject; } /** * Get the user name which authenticate against to. If the default user * is used, Null will be returned. * * @return user name */ public String getUser(){ return this.user; } /** * Set the service name which is used to setup GSSContext. * Program will use this name to require service ticket from KDC. * * @param name the service name used to require service ticket from KDC. */ public void setService(String name){ service = name; } /** * Get the service name. * * @return the service name used to require service ticket from KDC */ public String getService(){ return this.service; } /** * Get lifetime of current user. * * @return the remaining lifetime in seconds. If the default lifetime is * used, this value have no meaning. * */ public int getUserLifeTime(){ return userLifetime; } /** * Set lifetime of current user. * * @param time the lifetime in seconds * */ public void setUserLifeTime(int time){ userLifetime = time; } /** * Get lifetime of this context. * * @return the remaining lifetime in seconds. If the default lifetime is * used, this value have no meaning. */ public int getLifeTime(){ return contextLifetime; } /** * Set the lifetime for this context. * * @param time the lifetime in seconds */ public void setLifeTime(int time){ contextLifetime = time; } /* (non-Javadoc) * @see jcifs.smb.SmbExtendedAuthenticator#sessionSetup(jcifs.smb.SmbSession, jcifs.smb.ServerMessageBlock, jcifs.smb.ServerMessageBlock) */ public void sessionSetup( final SmbSession session, final ServerMessageBlock andx, final ServerMessageBlock andxResponse) throws SmbException { try { Subject.doAs(subject, new PrivilegedExceptionAction(){ public Object run() throws Exception{ setup(session, andx, andxResponse); return null; } }); } catch (PrivilegedActionException e) { if (e.getException() instanceof SmbException) { throw (SmbException) e.getException(); } throw new SmbException(e.getMessage(), e.getException()); } } private void setup(SmbSession session, ServerMessageBlock andx, ServerMessageBlock andxResponse) throws SmbAuthException, SmbException { Kerb5Context context = null; SpnegoContext spnego = null; try{ String host = session.transport.address.getHostAddress(); try{ host = session.transport.address.getHostName(); }catch(Throwable e){} context = createContext(host); spnego = new SpnegoContext(context.getGSSContext()); byte[] token = new byte[0]; Kerb5SessionSetupAndX request=null; Kerb5SessionSetupAndXResponse response = null; while(!spnego.isEstablished()){ token = spnego.initSecContext(token, 0, token.length); if(token != null){ request = new Kerb5SessionSetupAndX(session, null/*andx*/); request.getSecurityBlob().set(token); response = new Kerb5SessionSetupAndXResponse( andxResponse ); // if(session.transport.digest == null && // (session.transport.server.securityMode & 0x0f)!=0){ if(session.transport.digest == null && (session.transport.server.signaturesRequired || (session.transport.server.signaturesEnabled && SmbConstants.SIGNPREF))){ Key key = context.searchSessionKey(subject); if(key == null){ throw new SmbException("Not found the session key."); } request.digest = new SigningDigest(key.getEncoded()); } session.transport.send( request, response ); session.transport.digest = request.digest; token = response.getSecurityBlob().get(); } } session.setUid(response.uid); session.setSessionSetup(true); }catch (GSSException e) { e.printStackTrace(); throw new SmbException(e.getMessage()); }finally{ if(context != null){ try {context.dispose();} catch (GSSException e) {} } } } private Kerb5Context createContext(String host) throws GSSException{ Kerb5Context kerb5Context = new Kerb5Context( host, service, user, userLifetime, contextLifetime ); kerb5Context.getGSSContext().requestAnonymity(false); kerb5Context.getGSSContext().requestSequenceDet(false); kerb5Context.getGSSContext().requestMutualAuth(false); kerb5Context.getGSSContext().requestConf(false); kerb5Context.getGSSContext().requestInteg(false); kerb5Context.getGSSContext().requestReplayDet(false); return kerb5Context; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object arg0) { // >> SmbAuthenticator 11062008 //this method is called from SmbSession return this.getSubject()==((Kerb5Authenticator)arg0).getSubject(); // return false; // SmbAuthenticator 11062008<< } public String getDomain() { String realm = ""; if (subject != null) { Set pr=subject.getPrincipals(); for (Iterator ite = pr.iterator();ite.hasNext();){ try{ KerberosPrincipal entry = (KerberosPrincipal) ite.next(); realm = entry.getRealm(); break; }catch (Exception e){ continue; } } } if (realm.isEmpty()){ return getDefaultDomain(); } return realm; } private String getDefaultDomain(){ return Config.getProperty("jcifs.smb.client.domain", "?"); } } // SmbAuthenticator<<




© 2015 - 2024 Weber Informatics LLC | Privacy Policy