package com.celements.web.plugin.cmd;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.context.Execution;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.plugin.mailsender.MailConfiguration;
import com.xpn.xwiki.web.Utils;
/**
* The Mail Configuration must only be carefully changed to NOT generate security issues.
* It is important that the default smtp-server configuration for smtp-user, smtp-password
* smtp-host, smtp-port AND extra-props must be kept integer. Thus all or none must be
* taken from the XWikiPreferences. They MUST NOT BE MIXED with default server
* configuration. If they get mixed and default server configuration includes smtp-auth
* username and password they can get undisclosed in the following attack scenario: The
* smtp-host config is overwritten to some special server tracking username and passwords.
* Mixing the configuration leads to the server default username and password would be
* sent to this unfriendly server.
*
* @author fabian
* @since 2.34.0
*/
public class CelMailConfiguration extends MailConfiguration {
private static Log LOGGER = LogFactory.getFactory().getInstance(CelMailConfiguration.class);
public static final String MAIL_DEFAULT_ADMIN_EMAIL_KEY = "celements.mail.default.admin_email";
public static final String MAIL_DEFAULT_SMTP_FROM_KEY = "celements.mail.default.smtp_from";
public CelMailConfiguration() {
setPort(-1);
setHost("");
}
void readVirtualWikiHostConfiguration() {
String smtpServer = getXWiki().getXWikiPreference("smtp_server", getContext());
if (!StringUtils.isBlank(smtpServer)) {
setHost(smtpServer);
}
int port = getXWiki().getXWikiPreferenceAsInt("smtp_port", -1, getContext());
setPort(port);
String smtpServerUsername = getXWiki().getXWikiPreference("smtp_server_username", getContext());
String smtpServerPassword = getXWiki().getXWikiPreference("smtp_server_password", getContext());
if (!StringUtils.isEmpty(smtpServerUsername) && !StringUtils.isEmpty(smtpServerPassword)) {
setSmtpUsername(smtpServerUsername);
setSmtpPassword(smtpServerPassword);
}
String javaMailExtraProps = getXWiki().getXWikiPreference("javamail_extra_props", getContext());
if (!StringUtils.isEmpty(javaMailExtraProps)) {
setExtraProperties(javaMailExtraProps);
}
}
public String getDefaultAdminSenderAddress() {
return getXWiki().getXWikiPreference("admin_email", MAIL_DEFAULT_ADMIN_EMAIL_KEY, "",
getContext());
}
public String getDefaultGeneralSenderAddress() {
return getXWiki().getXWikiPreference("smtp_from", MAIL_DEFAULT_SMTP_FROM_KEY, "", getContext());
}
boolean usesAuthentication_localConfig() {
return !StringUtils.isEmpty(getSmtpUsername_internal()) && !StringUtils.isEmpty(
getSmtpPassword_internal());
}
void checkHostConfiguration() {
if (noHostConfig()) {
readVirtualWikiHostConfiguration();
if (noHostConfig()) {
readServerDefaultHostConfiguration();
}
}
}
void readServerDefaultHostConfiguration() {
String smtpServer = getXWiki().Param("celements.mail.default.smtp_server", "");
super.setHost(smtpServer);
int port = (int) getXWiki().ParamAsLong("celements.mail.default.smtp_port", -1);
setPort(port);
String smtpServerUsername = getXWiki().Param("celements.mail.default.smtp_server_username", "");
String smtpServerPassword = getXWiki().Param("celements.mail.default.smtp_server_password", "");
if (!StringUtils.isEmpty(smtpServerUsername) && !StringUtils.isEmpty(smtpServerPassword)) {
super.setSmtpUsername(smtpServerUsername);
super.setSmtpPassword(smtpServerPassword);
}
String javaMailExtraProps = getXWiki().Param("celements.mail.default.javamail_extra_props", "");
if (!StringUtils.isEmpty(javaMailExtraProps)) {
setExtraProperties(javaMailExtraProps);
}
LOGGER.debug("setting default HostConfiguration smtp_server_username [" + smtpServerUsername
+ "] using smtp-password [" + !"".equals(smtpServerPassword) + "] and host [" + smtpServer
+ ":" + port + "] and javaMailExtraProps [" + javaMailExtraProps + "].");
}
boolean noHostConfig() {
Properties testProperties = new Properties();
appendExtraProperties_internal(testProperties, true);
return (!usesAuthentication_localConfig() && StringUtils.isEmpty(getHost_internal())
&& (getPort_internal() <= -1) && testProperties.isEmpty());
}
String getHost_internal() {
return super.getHost();
}
@Override
public String getHost() {
checkHostConfiguration();
if (!StringUtils.isEmpty(getHost_internal())) {
return getHost_internal();
} else if (noHostConfig()) {
return "localhost";
}
return "";
}
int getPort_internal() {
return super.getPort();
}
@Override
public int getPort() {
checkHostConfiguration();
if (getPort_internal() > -1) {
return getPort_internal();
} else {
return 25;
}
}
@Override
public String getFrom() {
if (StringUtils.isEmpty(super.getFrom())) {
super.setFrom(getDefaultGeneralSenderAddress());
}
if (StringUtils.isEmpty(super.getFrom())) {
super.setFrom(getDefaultAdminSenderAddress());
}
return super.getFrom();
}
@Override
public String getSmtpUsername() {
checkHostConfiguration();
return getSmtpUsername_internal();
}
String getSmtpUsername_internal() {
return super.getSmtpUsername();
}
@Override
public String getSmtpPassword() {
checkHostConfiguration();
return getSmtpPassword_internal();
}
String getSmtpPassword_internal() {
return super.getSmtpPassword();
}
@Override
public void setExtraProperties(String extraPropertiesString) {
String extraProps = extraPropertiesString;
if (!StringUtils.isEmpty(extraPropertiesString)) {
extraProps = extraPropertiesString.replaceAll(",", "\n");
}
super.setExtraProperties(extraProps);
}
@Override
public void appendExtraPropertiesTo(Properties externalProperties, boolean overwrite) {
checkHostConfiguration();
appendExtraProperties_internal(externalProperties, overwrite);
}
void appendExtraProperties_internal(Properties externalProperties, boolean overwrite) {
super.appendExtraPropertiesTo(externalProperties, overwrite);
}
private XWiki getXWiki() {
return getContext().getWiki();
}
private XWikiContext getContext() {
return (XWikiContext) Utils.getComponent(Execution.class).getContext().getProperty(
"xwikicontext");
}
}