|
|
Author: elecharny
Date: Mon Dec 1 15:59:32 2008
New Revision: 722296
URL: http://svn.apache.org/viewvc?rev=722296&view=rev
Log:
Added all the needed code to handle the OOM protection, by limitating the PDU
size.
The current limit is Integer.MAX_VALUE.
Modified:
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
Modified:
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
(original)
+++
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
Mon Dec 1 15:59:32 2008
@@ -63,6 +63,12 @@
/** The grammar end transition flag */
protected boolean grammarEndAllowed;
+ /** A counter for the decoded bytes */
+ protected int decodeBytes;
+
+ /** The maximum allowed size for a PDU. Default to MAX int value */
+ protected int maxPDUSize = Integer.MAX_VALUE;
+
/** The incremental id used to tag TLVs */
private int id = 0;
@@ -229,4 +235,52 @@
{
return tlv.getId();
}
+
+
+ /**
+ * @return The number of decoded bytes for this message. This is used
+ * to control the PDU size and avoid PDU exceeding the maximum allowed
+ * size to break the server.
+ */
+ public int getDecodeBytes()
+ {
+ return decodeBytes;
+ }
+
+
+ /**
+ * Increment the decodedBytes by the latest received buffer's size.
+ * @param nb The buffer size.
+ */
+ public void incrementDecodeBytes( int nb )
+ {
+ decodeBytes += nb;
+ }
+
+
+ /**
+ * @return The maximum PDU size.
+ */
+ public int getMaxPDUSize()
+ {
+ return maxPDUSize;
+ }
+
+
+ /**
+ * Set the maximum PDU size.
+ * @param maxPDUSize The maximum PDU size (if negative or null, will be
+ * replaced by the max integer value)
+ */
+ public void setMaxPDUSize( int maxPDUSize )
+ {
+ if ( maxPDUSize > 0 )
+ {
+ this.maxPDUSize = maxPDUSize;
+ }
+ else
+ {
+ this.maxPDUSize = Integer.MAX_VALUE;
+ }
+ }
}
Modified:
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
(original)
+++
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
Mon Dec 1 15:59:32 2008
@@ -47,10 +47,10 @@
// -----------------------------------------------------------------
/** The logger */
- private static final Logger log = LoggerFactory.getLogger(
Asn1Decoder.class );
+ private static final Logger LOG = LoggerFactory.getLogger(
Asn1Decoder.class );
/** A speedup for logger */
- private static final boolean IS_DEBUG = log.isDebugEnabled();
+ private static final boolean IS_DEBUG = LOG.isDebugEnabled();
/** This flag is used to indicate that there are more bytes in the stream
*/
private static final boolean MORE = true;
@@ -120,7 +120,7 @@
if ( IS_DEBUG )
{
byte tag = container.getCurrentTLV().getTag();
- log.debug( "Tag {} has been decoded",
Asn1StringUtils.dumpByte( tag ) );
+ LOG.debug( "Tag {} has been decoded",
Asn1StringUtils.dumpByte( tag ) );
}
return MORE;
@@ -157,7 +157,7 @@
if ( IS_DEBUG )
{
- log.debug( "TLV Tree : {}", sb.toString() );
+ LOG.debug( "TLV Tree : {}", sb.toString() );
}
}
@@ -232,7 +232,7 @@
if ( expectedLength > 4 )
{
- log.error( "Overflow : can't have more than 4 bytes long
length" );
+ LOG.error( "Overflow : can't have more than 4 bytes long
length" );
throw new DecoderException( "Overflow : can't have more
than 4 bytes long length" );
}
@@ -243,7 +243,7 @@
}
else
{
- log.error( "Length reserved extension used" );
+ LOG.error( "Length reserved extension used" );
throw new DecoderException( "Length reserved extension used" );
}
@@ -282,7 +282,7 @@
if ( IS_DEBUG )
{
- log.debug( " current byte : {}",
Asn1StringUtils.dumpByte( octet ) );
+ LOG.debug( " current byte : {}",
Asn1StringUtils.dumpByte( octet ) );
}
tlv.incLengthBytesRead();
@@ -362,7 +362,7 @@
if ( tlv == null )
{
- log.error( "The current container TLV is null." );
+ LOG.error( "The current container TLV is null." );
throw new DecoderException( "Current TLV is null" );
}
@@ -375,7 +375,7 @@
if ( IS_DEBUG )
{
- log.debug( "Parent length : {}", getParentLength( parentTLV ) );
+ LOG.debug( "Parent length : {}", getParentLength( parentTLV ) );
}
if ( parentTLV == null )
@@ -387,7 +387,7 @@
if ( IS_DEBUG )
{
- log.debug( "Root TLV[{}]", Integer.valueOf( length ) );
+ LOG.debug( "Root TLV[{}]", Integer.valueOf( length ) );
}
}
else
@@ -401,7 +401,7 @@
{
// The expected length is lower than the Value length of the
// current TLV. This is an error...
- log.error( "tlv[{}, {}]", Integer.valueOf( expectedLength ),
Integer.valueOf( currentLength ) );
+ LOG.error( "tlv[{}, {}]", Integer.valueOf( expectedLength ),
Integer.valueOf( currentLength ) );
throw new DecoderException( "The current Value length is above
the expected length" );
}
@@ -494,7 +494,7 @@
if ( IS_DEBUG )
{
- log.debug( "Length {} has been decoded", Integer.valueOf( length )
);
+ LOG.debug( "Length {} has been decoded", Integer.valueOf( length )
);
}
if ( length == 0 )
@@ -636,7 +636,7 @@
}
else
{
- log.error( "The PDU is decoded, but we should have had
more TLVs" );
+ LOG.error( "The PDU is decoded, but we should have had
more TLVs" );
throw new DecoderException( "Truncated PDU. Some elements
are lacking, accordingly to the grammar" );
}
}
@@ -724,12 +724,23 @@
*/
boolean hasRemaining = stream.hasRemaining();
+
+ // Increment the PDU size counter.
+ container.incrementDecodeBytes( stream.remaining() );
+
+ if ( container.getDecodeBytes() > container.getMaxPDUSize() )
+ {
+ String message = "The PDU current size (" +
container.getDecodeBytes() +
+ ") exceeds the maximum allowed PDU size (" +
container.getMaxPDUSize() +")";
+ LOG.error( message );
+ throw new DecoderException( message );
+ }
if ( IS_DEBUG )
{
- log.debug( ">>>==========================================" );
- log.debug( "--> Decoding a PDU" );
- log.debug( ">>>------------------------------------------" );
+ LOG.debug( ">>>==========================================" );
+ LOG.debug( "--> Decoding a PDU" );
+ LOG.debug( ">>>------------------------------------------" );
}
while ( hasRemaining )
@@ -737,17 +748,17 @@
if ( IS_DEBUG )
{
- log.debug( "--- State = {} ---", stateToString(
container.getState() ) );
+ LOG.debug( "--- State = {} ---", stateToString(
container.getState() ) );
if ( stream.hasRemaining() )
{
byte octet = stream.get( stream.position() );
- log.debug( " current byte : {}",
Asn1StringUtils.dumpByte( octet ) );
+ LOG.debug( " current byte : {}",
Asn1StringUtils.dumpByte( octet ) );
}
else
{
- log.debug( " no more byte to decode in the stream" );
+ LOG.debug( " no more byte to decode in the stream" );
}
}
@@ -800,7 +811,7 @@
case TLVStateEnum.PDU_DECODED:
// We have to deal with the case where there are
// more bytes in the buffer, but the PDU has been decoded.
- log.warn( "The PDU has been fully decoded but there are
still bytes in the buffer." );
+ LOG.warn( "The PDU has been fully decoded but there are
still bytes in the buffer." );
hasRemaining = false;
@@ -813,32 +824,32 @@
if ( IS_DEBUG )
{
- log.debug( "<<<------------------------------------------" );
+ LOG.debug( "<<<------------------------------------------" );
if ( container.getState() == TLVStateEnum.PDU_DECODED )
{
if ( container.getCurrentTLV() != null )
{
- log.debug( "<-- Stop decoding : {}",
container.getCurrentTLV().toString() );
+ LOG.debug( "<-- Stop decoding : {}",
container.getCurrentTLV().toString() );
}
else
{
- log.debug( "<-- Stop decoding : null current TLV" );
+ LOG.debug( "<-- Stop decoding : null current TLV" );
}
}
else
{
if ( container.getCurrentTLV() != null )
{
- log.debug( "<-- End decoding : {}",
container.getCurrentTLV().toString() );
+ LOG.debug( "<-- End decoding : {}",
container.getCurrentTLV().toString() );
}
else
{
- log.debug( "<-- End decoding : null current TLV" );
+ LOG.debug( "<-- End decoding : null current TLV" );
}
}
- log.debug( "<<<==========================================" );
+ LOG.debug( "<<<==========================================" );
}
return;
Modified:
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
(original)
+++
directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
Mon Dec 1 15:59:32 2008
@@ -139,4 +139,33 @@
* @return a unique value representing the current TLV id
*/
int getTlvId();
+
+
+ /**
+ * @return The number of decoded bytes for this message. This is used
+ * to control the PDU size and avoid PDU exceeding the maximum allowed
+ * size to break the server.
+ */
+ int getDecodeBytes();
+
+
+ /**
+ * Increment the decodedBytes by the latest received buffer's size.
+ * @param nb The buffer size.
+ */
+ void incrementDecodeBytes( int nb );
+
+
+ /**
+ * @return The maximum PDU size.
+ */
+ int getMaxPDUSize();
+
+
+ /**
+ * Set the maximum PDU size.
+ * @param maxPDUSize The maximum PDU size (if negative or null, will be
+ * replaced by the max integer value)
+ */
+ void setMaxPDUSize( int maxPDUSize );
}
Modified:
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
(original)
+++
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
Mon Dec 1 15:59:32 2008
@@ -114,6 +114,7 @@
ldapMessage = null;
messageId = 0;
currentControl = null;
+ decodeBytes = 0;
}
Modified:
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
(original)
+++
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
Mon Dec 1 15:59:32 2008
@@ -69,12 +69,15 @@
*
* @param provider the owning provider.
* @param binaryAttributeDetector checks for binary attributes
+ * @param maxPDUSize the maximum size a PDU can be
*/
- public TwixDecoder( Provider provider, BinaryAttributeDetector
binaryAttributeDetector )
+ public TwixDecoder( Provider provider, BinaryAttributeDetector
binaryAttributeDetector, int maxPDUSize )
{
this.provider = provider;
- this.ldapMessageContainer = new LdapMessageContainer(
binaryAttributeDetector );
- this.ldapDecoder = new LdapDecoder();
+ ldapMessageContainer = new LdapMessageContainer(
binaryAttributeDetector );
+ ldapDecoder = new LdapDecoder();
+
+ ldapMessageContainer.setMaxPDUSize( maxPDUSize );
}
Modified:
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
(original)
+++
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
Mon Dec 1 15:59:32 2008
@@ -85,8 +85,8 @@
* @throws org.apache.directory.shared.ldap.message.spi.ProviderException
* if the provider or its decoder cannot be found
*/
- public ProviderDecoder getDecoder( BinaryAttributeDetector
binaryAttributeDetector ) throws ProviderException
+ public ProviderDecoder getDecoder( BinaryAttributeDetector
binaryAttributeDetector, int maxPDUSize ) throws ProviderException
{
- return new TwixDecoder( this, binaryAttributeDetector );
+ return new TwixDecoder( this, binaryAttributeDetector, maxPDUSize );
}
}
Modified:
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
(original)
+++
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
Mon Dec 1 15:59:32 2008
@@ -63,11 +63,25 @@
*/
public MessageDecoder( BinaryAttributeDetector binaryAttributeDetector )
throws MessageException
{
+ this( binaryAttributeDetector, Integer.MAX_VALUE );
+ }
+
+
+ /**
+ * Creates a MessageDecoder using default properties for enabling a BER
+ * library provider.
+ *
+ * @param binaryAttributeDetector detects whether or not an attribute is
binary
+ * @param maxPDUSize the maximum size a PDU can be
+ * @throws MessageException if there is a problem creating this decoder.
+ */
+ public MessageDecoder( BinaryAttributeDetector binaryAttributeDetector,
int maxPDUSize ) throws MessageException
+ {
// We need to get the encoder class name
Hashtable<Object, Object> providerEnv = Provider.getEnvironment();
this.provider = Provider.getProvider( providerEnv );
- this.decoder = this.provider.getDecoder( binaryAttributeDetector );
+ this.decoder = this.provider.getDecoder( binaryAttributeDetector,
maxPDUSize );
this.decoder.setCallback( new DecoderCallback()
{
public void decodeOccurred( StatefulDecoder decoder, Object
decoded )
Modified:
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
URL:
http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
---
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
(original)
+++
directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
Mon Dec 1 15:59:32 2008
@@ -176,8 +176,10 @@
* @return the provider's decoder.
* @throws ProviderException if the provider or its decoder cannot be found
* @param binaryAttributeDetector detects whether or not attributes are
binary
+ * @param maxPDUSize the maximum size a PDU can be
*/
- public abstract ProviderDecoder getDecoder( BinaryAttributeDetector
binaryAttributeDetector )
+ public abstract ProviderDecoder getDecoder( BinaryAttributeDetector
binaryAttributeDetector,
+ int maxPDUSize )
throws ProviderException;
|
|