package org.apereo.cas.support.spnego.authentication.handler.support; import com.google.common.base.Throwables; import jcifs.Config; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import javax.annotation.PostConstruct; import java.net.URL; /** * Configuration helper for JCIFS and the Spring framework. * * @author Marc-Antoine Garrigue * @author Arnaud Lesueur * @author Scott Battaglia * @since 4.2.0 */ public class JcifsConfig { private static final String DEFAULT_LOGIN_CONFIG = "/login.conf"; private static final String SYS_PROP_USE_SUBJECT_CRED_ONLY = "javax.security.auth.useSubjectCredsOnly"; private static final String SYS_PROP_LOGIN_CONF = "java.security.auth.login.config"; private static final String SYS_PROP_KERBEROS_DEBUG = "sun.security.krb5.debug"; private static final String SYS_PROP_KERBEROS_CONF = "java.security.krb5.conf"; private static final String SYS_PROP_KERBEROS_REALM = "java.security.krb5.realm"; private static final String SYS_PROP_KERBEROS_KDC = "java.security.krb5.kdc"; private static final String JCIFS_PROP_DOMAIN_CONTROLLER = "jcifs.http.domainController"; private static final String JCIFS_PROP_NETBIOS_WINS = "jcifs.netbios.wins"; private static final String JCIFS_PROP_CLIENT_DOMAIN = "jcifs.smb.client.domain"; private static final String JCIFS_PROP_CLIENT_USERNAME = "jcifs.smb.client.username"; private static final String JCIFS_PROP_CLIENT_PASSWORD = "jcifs.smb.client.password"; private static final String JCIFS_PROP_CLIENT_SOTIMEOUT = "jcifs.smb.client.soTimeout"; private static final String JCIFS_PROP_NETBIOS_CACHE_POLICY = "jcifs.netbios.cachePolicy"; /** * -- the service principal you just created. Using the previous example, * this would be "HTTP/mybox at DOMAIN.COM". */ private static final String JCIFS_PROP_SERVICE_PRINCIPAL = "jcifs.spnego.servicePrincipal"; /** * The password for the service principal account, required only if you * decide not to use keytab. */ private static final String JCIFS_PROP_SERVICE_PASSWORD = "jcifs.spnego.servicePassword"; private static final Logger LOGGER = LoggerFactory.getLogger(JcifsConfig.class); private String loginConf; @Autowired private ResourceLoader resourceLoader; /** * Instantiates a new jCIFS config. */ public JcifsConfig() { Config.setProperty(JCIFS_PROP_CLIENT_SOTIMEOUT, "300000"); Config.setProperty(JCIFS_PROP_NETBIOS_CACHE_POLICY, "600"); } /** * Init. */ @PostConstruct public void init() { configureJaasLoginConfig(); } /** * Configure jaas login config location and set it as a system property. */ protected void configureJaasLoginConfig() { try { final String propValue = System.getProperty(SYS_PROP_LOGIN_CONF); if (StringUtils.isNotBlank(propValue)) { LOGGER.info("Found login config [{}] in system property [{}]", propValue, SYS_PROP_LOGIN_CONF); if (StringUtils.isNotBlank(this.loginConf)) { LOGGER.warn("Configured login config for CAS under [{}] will be ignored", this.loginConf); } } else { final String loginConf = StringUtils.isBlank(this.loginConf) ? DEFAULT_LOGIN_CONFIG : this.loginConf; LOGGER.debug("Attempting to load login config from [{}]", loginConf); final Resource res = this.resourceLoader.getResource(loginConf); if (res != null && res.exists()) { final String urlPath = res.getURL().toExternalForm(); LOGGER.debug("Located login config [{}] and configured it under [{}]", urlPath, SYS_PROP_LOGIN_CONF); System.setProperty(SYS_PROP_LOGIN_CONF, urlPath); } else { final URL url = getClass().getResource("/jcifs/http/login.conf"); if (url != null) { LOGGER.debug("Falling back unto default login config [{}] under [{}]", url.toExternalForm(), SYS_PROP_LOGIN_CONF); System.setProperty(SYS_PROP_LOGIN_CONF, url.toExternalForm()); } } LOGGER.debug("configured login configuration path : [{}]", propValue); } } catch (final Exception e) { throw Throwables.propagate(e); } } /** * Sets the jcifs service password. * * @param jcifsServicePassword the new jcifs service password */ public void setJcifsServicePassword(final String jcifsServicePassword) { if (StringUtils.isNotBlank(jcifsServicePassword)) { LOGGER.debug("jcifsServicePassword is set to *****"); Config.setProperty(JCIFS_PROP_SERVICE_PASSWORD, jcifsServicePassword); } } /** * Sets the jcifs service principal. * * @param jcifsServicePrincipal the new jcifs service principal */ public void setJcifsServicePrincipal(final String jcifsServicePrincipal) { if (StringUtils.isNotBlank(jcifsServicePrincipal)) { LOGGER.debug("jcifsServicePrincipal is set to [{}]", jcifsServicePrincipal); Config.setProperty(JCIFS_PROP_SERVICE_PRINCIPAL, jcifsServicePrincipal); } } /** * Sets the kerberos conf. * * @param kerberosConf the new kerberos conf */ public void setKerberosConf(final String kerberosConf) { if (StringUtils.isNotBlank(kerberosConf)) { LOGGER.debug("kerberosConf is set to :[{}]", kerberosConf); System.setProperty(SYS_PROP_KERBEROS_CONF, kerberosConf); } } /** * Sets the kerberos kdc. * * @param kerberosKdc the new kerberos kdc */ public void setKerberosKdc(final String kerberosKdc) { if (StringUtils.isNotBlank(kerberosKdc)) { LOGGER.debug("kerberosKdc is set to : [{}]", kerberosKdc); System.setProperty(SYS_PROP_KERBEROS_KDC, kerberosKdc); } } /** * Sets the kerberos realm. * * @param kerberosRealm the new kerberos realm */ public void setKerberosRealm(final String kerberosRealm) { if (StringUtils.isNotBlank(kerberosRealm)) { LOGGER.debug("kerberosRealm is set to :[{}]", kerberosRealm); System.setProperty(SYS_PROP_KERBEROS_REALM, kerberosRealm); } } public void setLoginConf(final String loginConf) { this.loginConf = loginConf; } /** * Sets the use subject creds only. * * @param useSubjectCredsOnly the new use subject creds only */ public void setUseSubjectCredsOnly(final boolean useSubjectCredsOnly) { LOGGER.debug("useSubjectCredsOnly is set to [{}]", useSubjectCredsOnly); System.setProperty(SYS_PROP_USE_SUBJECT_CRED_ONLY, Boolean.toString(useSubjectCredsOnly)); } /** * Sets the kerberos debug. * * @param kerberosDebug the new kerberos debug */ public void setKerberosDebug(final String kerberosDebug) { if (StringUtils.isNotBlank(kerberosDebug)) { LOGGER.debug("kerberosDebug is set to : [{}]", kerberosDebug); System.setProperty(SYS_PROP_KERBEROS_DEBUG, kerberosDebug); } } /** * @param jcifsDomain the jcifsDomain to set */ public void setJcifsDomain(final String jcifsDomain) { if (StringUtils.isNotBlank(jcifsDomain)) { LOGGER.debug("jcifsDomain is set to [{}]", jcifsDomain); Config.setProperty(JCIFS_PROP_CLIENT_DOMAIN, jcifsDomain); } } /** * @param jcifsDomainController the jcifsDomainController to set */ public void setJcifsDomainController(final String jcifsDomainController) { if (StringUtils.isNotBlank(jcifsDomainController)) { LOGGER.debug("jcifsDomainController is set to [{}]", jcifsDomainController); Config.setProperty(JCIFS_PROP_DOMAIN_CONTROLLER, jcifsDomainController); } } /** * @param jcifsPassword the jcifsPassword to set */ public void setJcifsPassword(final String jcifsPassword) { if (StringUtils.isNotBlank(jcifsPassword)) { Config.setProperty(JCIFS_PROP_CLIENT_PASSWORD, jcifsPassword); LOGGER.debug("jcifsPassword is set to *****"); } } /** * @param jcifsUsername the jcifsUsername to set */ public void setJcifsUsername(final String jcifsUsername) { if (StringUtils.isNotBlank(jcifsUsername)) { LOGGER.debug("jcifsUsername is set to [{}]", jcifsUsername); Config.setProperty(JCIFS_PROP_CLIENT_USERNAME, jcifsUsername); } } /** * @param jcifsNetbiosWins the jcifsNetbiosWins to set */ public void setJcifsNetbiosWins(final String jcifsNetbiosWins) { if (StringUtils.isNotBlank(jcifsNetbiosWins)) { LOGGER.debug("jcifsNetbiosWins is set to [{}]", jcifsNetbiosWins); Config.setProperty(JCIFS_PROP_NETBIOS_WINS, jcifsNetbiosWins); } } /** * Sets jcifs netbios cache policy. * * @param policy the policy */ public void setJcifsNetbiosCachePolicy(final long policy) { if (policy > 0) { LOGGER.debug("jcifsNetbiosCachePolicy is set to [{}]", policy); Config.setProperty(JCIFS_PROP_NETBIOS_CACHE_POLICY, String.valueOf(policy)); } } /** * Sets jcifs socket timeout. * * @param timeout the timeout */ public void setJcifsSocketTimeout(final long timeout) { if (timeout > 0) { LOGGER.debug("jcifsSocketTimeout is set to [{}]", timeout); Config.setProperty(JCIFS_PROP_CLIENT_SOTIMEOUT, String.valueOf(timeout)); } } }