This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit b962835f98b905286b78c414d5aaec2d0e711f75 Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Jan 21 14:24:33 2020 +0000 Rename requiredSecret to secret and add secretRequired AJP Connector will not start if secretRequired="true" and secret is set to null or zero length String. --- .../org/apache/coyote/ajp/AbstractAjpProtocol.java | 52 ++++++++++++++++++++-- java/org/apache/coyote/ajp/AjpProcessor.java | 18 +++++--- java/org/apache/coyote/ajp/LocalStrings.properties | 1 + webapps/docs/changelog.xml | 8 ++++ webapps/docs/config/ajp.xml | 12 ++++- 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java index eb9c4dc..7403db0 100644 --- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java +++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java @@ -143,14 +143,48 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { } - private String requiredSecret = null; + private String secret = null; + /** + * Set the secret that must be included with every request. + * + * @param secret The required secret + */ + public void setSecret(String secret) { + this.secret = secret; + } + protected String getSecret() { + return secret; + } /** * Set the required secret that must be included with every request. * * @param requiredSecret The required secret + * + * @deprecated Replaced by {@link #setSecret(String)}. + * Will be removed in Tomcat 11 onwards */ + @Deprecated public void setRequiredSecret(String requiredSecret) { - this.requiredSecret = requiredSecret; + setSecret(requiredSecret); + } + /** + * @return The current secret + * + * @deprecated Replaced by {@link #getSecret()}. + * Will be removed in Tomcat 11 onwards + */ + @Deprecated + protected String getRequiredSecret() { + return getSecret(); + } + + + private boolean secretRequired = true; + public void setSecretRequired(boolean secretRequired) { + this.secretRequired = secretRequired; + } + public boolean getSecretRequired() { + return secretRequired; } @@ -202,7 +236,7 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { processor.setAjpFlush(getAjpFlush()); processor.setTomcatAuthentication(getTomcatAuthentication()); processor.setTomcatAuthorization(getTomcatAuthorization()); - processor.setRequiredSecret(requiredSecret); + processor.setSecret(secret); processor.setKeepAliveTimeout(getKeepAliveTimeout()); processor.setClientCertProvider(getClientCertProvider()); processor.setSendReasonPhrase(getSendReasonPhrase()); @@ -216,4 +250,16 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { throw new IllegalStateException(sm.getString("ajpprotocol.noUpgradeHandler", upgradeToken.getHttpUpgradeHandler().getClass().getName())); } + + + @Override + public void init() throws Exception { + if (getSecretRequired()) { + String secret = getSecret(); + if (secret == null || secret.length() == 0) { + throw new IllegalArgumentException(sm.getString("ajpprotocol.nosecret")); + } + } + super.init(); + } } diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java index c827455..745cc6f 100644 --- a/java/org/apache/coyote/ajp/AjpProcessor.java +++ b/java/org/apache/coyote/ajp/AjpProcessor.java @@ -322,9 +322,13 @@ public class AjpProcessor extends AbstractProcessor { /** * Required secret. */ - private String requiredSecret = null; + private String secret = null; + @Deprecated public void setRequiredSecret(String requiredSecret) { - this.requiredSecret = requiredSecret; + setSecret(requiredSecret); + } + public void setSecret(String secret) { + this.secret = secret; } @@ -782,7 +786,7 @@ public class AjpProcessor extends AbstractProcessor { } // Decode extra attributes - boolean secret = false; + boolean secretPresentInRequest = false; byte attributeCode; while ((attributeCode = requestHeaderMessage.getByte()) != Constants.SC_A_ARE_DONE) { @@ -883,9 +887,9 @@ public class AjpProcessor extends AbstractProcessor { case Constants.SC_A_SECRET: requestHeaderMessage.getBytes(tmpMB); - if (requiredSecret != null) { - secret = true; - if (!tmpMB.equals(requiredSecret)) { + if (secret != null) { + secretPresentInRequest = true; + if (!tmpMB.equals(secret)) { response.setStatus(403); setErrorState(ErrorState.CLOSE_CLEAN, null); } @@ -901,7 +905,7 @@ public class AjpProcessor extends AbstractProcessor { } // Check if secret was submitted if required - if ((requiredSecret != null) && !secret) { + if ((secret != null) && !secretPresentInRequest) { response.setStatus(403); setErrorState(ErrorState.CLOSE_CLEAN, null); } diff --git a/java/org/apache/coyote/ajp/LocalStrings.properties b/java/org/apache/coyote/ajp/LocalStrings.properties index 124f257..4dbaf3f 100644 --- a/java/org/apache/coyote/ajp/LocalStrings.properties +++ b/java/org/apache/coyote/ajp/LocalStrings.properties @@ -32,5 +32,6 @@ ajpprocessor.request.process=Error processing request ajpprotocol.noBio=The AJP BIO connector has been removed in Tomcat 8.5.x onwards. The AJP BIO connector configuration has been automatically switched to use the AJP NIO connector instead. ajpprotocol.noSSL=SSL is not supported with AJP. The SSL host configuration for [{0}] was ignored +ajpprotocol.nosecret=The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid. ajpprotocol.noUpgrade=Upgrade is not supported with AJP. The UpgradeProtocol configuration for [{0}] was ignored ajpprotocol.noUpgradeHandler=Upgrade is not supported with AJP. The HttpUpgradeHandler [{0}] can not be processed diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8091e04..bee08d8 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -187,6 +187,14 @@ Change the default bind address for the AJP/1.3 connector to be the loopback address. (markt) </update> + <add> + Rename the <code>requiredSecret</code> attribute of the AJP/1.3 + Connector to <code>secret</code> and add a new attribute + <code>secretRequired</code> that defaults to <code>true</code>. When + <code>secretRequired</code> is <code>true</code> the AJP/1.3 Connector + will not start unless the <code>secret</code> attribute is configured to + a non-null, non-zero length String. (markt) + </add> </changelog> </subsection> <subsection name="Jasper"> diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml index 80a7fe4..b75d5c6 100644 --- a/webapps/docs/config/ajp.xml +++ b/webapps/docs/config/ajp.xml @@ -437,8 +437,18 @@ expected concurrent requests (synchronous and asynchronous).</p> </attribute> - <attribute name="requiredSecret" required="false"> + <attribute name="secret" required="false"> <p>Only requests from workers with this secret keyword will be accepted. + The default value is <code>null</code>. This attrbute must be specified + with a non-null, non-zero length value unless + <strong>secretRequired</strong> is explicitly configured to be + <code>false</code>.</p> + </attribute> + + <attribute name="secretRequired" required="false"> + <p>If this attribute is <code>true</code>, the AJP Connector will only + start if the <strong>secret</strong> attribute is configured with a + non-null, non-zero length value. The default value is <code>true</code>. </p> </attribute> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org