1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.ber ;
18  
19  
20  import org.apache.asn1.codec.stateful.CallbackHistory;
21  
22  import java.nio.ByteBuffer;
23  
24  
25  /***
26   * $todo$ doc me
27   *
28   * @author <a href="mailto:dev@directory.apache.org">
29   * Apache Directory Project</a>
30   * @version $Rev: 158144 $
31   */
32  public class LdapMessageTests extends AbstractDecoderTestCase
33  {
34      TupleTreeDecoder ttd = null ;
35      CallbackHistory history = null ;
36      
37      
38      public LdapMessageTests()
39      {
40          super ( LdapMessageTests.class.getName() ) ;
41      }
42      
43      
44      /* (non-Javadoc)
45       * @see org.apache.asn1.ber.AbstractDecoderTestCase#setUp()
46       */
47      protected void setUp() throws Exception
48      {
49          super.setUp();
50          
51          ttd = new TupleTreeDecoder() ;
52          history = new CallbackHistory( 1 ) ;
53          ttd.setCallback( history ) ;
54      }
55      
56      
57      /* (non-Javadoc)
58       * @see org.apache.asn1.ber.AbstractDecoderTestCase#tearDown()
59       */
60      protected void tearDown() throws Exception
61      {
62          super.tearDown();
63          
64          ttd = null ;
65          history = null ;
66      }
67      
68      
69      /***
70       * Creates a tuple node tree from a message.
71       * 
72       * @param pdu the message to encode and decode
73       * @return
74       * @throws Exception
75       */
76      public DefaultMutableTupleNode roundTripTest( byte[] pdu ) throws Exception
77      {
78          DefaultMutableTupleNode node = null ;
79          ByteBuffer buf1 = ByteBuffer.wrap( pdu ) ;
80          ttd.decode( buf1 ) ;
81          node = ( DefaultMutableTupleNode ) history.getMostRecent() ;
82  
83          ByteBuffer buf2 = ByteBuffer.allocate( node.size() ) ;
84          node.encode( buf2 ) ;
85          assertTrue( buf1.equals( buf2 ) ) ;
86  
87          return node ;
88      }
89  
90      public void testBindMessage() throws Exception
91      {
92          byte[] pdu = {0x30, 0x33, 0x02, 0x01, 0x01, 0x60, 0x2E, 0x02, 0x01, 0x03, 0x04, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0xFFFFFF80, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64};
93  
94          decode( pdu ) ;
95          roundTripTest( pdu ) ;
96          assertFalse( tlvList.isEmpty() ) ;
97      }
98  
99      public void testAddMessage() throws Exception
100     {
101         byte[] pdu = {0x30, 0x6D, 0x02, 0x01, 0x01, 0x68, 0x68, 0x04, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0x30, 0x45, 0x30, 0x0F, 0x04, 0x05, 0x61, 0x74, 0x74, 0x72, 0x31, 0x31, 0x06, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x30, 0x30, 0x15, 0x04, 0x05, 0x61, 0x74, 0x74, 0x72, 0x32, 0x31, 0x0C, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x31, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x30, 0x30, 0x1B, 0x04, 0x05, 0x61, 0x74, 0x74, 0x72, 0x30, 0x31, 0x12, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x30, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x31, 0x04, 0x04, 0x76, 0x61, 0x6C, 0x32};
102 
103         decode( pdu ) ;
104         roundTripTest( pdu ) ;
105         assertFalse( tlvList.isEmpty() ) ;
106     }
107 
108 
109     public void testDeleteMessage() throws Exception
110     {
111         byte[] pdu = {0x30, 0x24, 0x02, 0x01, 0x01, 0x4A, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D};
112 
113         decode( pdu ) ;
114         roundTripTest( pdu ) ;
115         assertFalse( tlvList.isEmpty() ) ;
116     }
117 
118 
119     public void testAbandonMessage() throws Exception
120     {
121         byte[] pdu = new byte[] {0x30, 0x06, 0x02, 0x01, 0x01, 0x50, 0x01, 0x03};
122 
123         decode( pdu ) ;
124         roundTripTest( pdu ) ;
125         assertFalse( tlvList.isEmpty() ) ;
126     }
127 
128 
129     public void testCompareMessage() throws Exception
130     {
131         byte[] pdu = {0x30, 0x3D, 0x02, 0x01, 0x01, 0x6E, 0x38, 0x04, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0x30, 0x15, 0x04, 0x08, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x74, 0x72, 0x04, 0x09, 0x74, 0x65, 0x73, 0x74, 0x76, 0x61, 0x6C, 0x75, 0x65};
132 
133         decode( pdu ) ;
134         roundTripTest( pdu ) ;
135         assertFalse( tlvList.isEmpty() ) ;
136     }
137 
138 
139     public void testExtendedMessage() throws Exception
140     {
141         byte[] pdu = {0x30, 0x22, 0x02, 0x01, 0x01, 0x77, 0x1D, 0xFFFFFF80, 0x0E, 0x31, 0x32, 0x33, 0x34, 0x2E, 0x31, 0x32, 0x33, 0x34, 0x2E, 0x31, 0x33, 0x32, 0x34, 0xFFFFFF81, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};
142 
143         decode( pdu ) ;
144         roundTripTest( pdu ) ;
145         assertFalse( tlvList.isEmpty() ) ;
146     }
147 
148 
149     public void testModifyDnMessage() throws Exception
150     {
151         byte[] pdu = {0x30, 0x45, 0x02, 0x01, 0x01, 0x6C, 0x40, 0x04, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0x04, 0x07, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6F, 0x6B, 0x01, 0x01, 0xFFFFFFFF, 0xFFFFFF80, 0x11, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D};
152 
153         decode( pdu ) ;
154         roundTripTest( pdu ) ;
155         assertFalse( tlvList.isEmpty() ) ;
156     }
157 
158 
159     /* ------------------------------------------------------------------------
160      
161 Here's what the modify message looks like:
162      
163 LDAP Modify Operation without any modification items
164 dn = "uid=akarasulu,dc=example,dc=com"
165 message id = 17
166 
167 [
168 0  -> 48  0x30, 0011 0000 (const) Universal id = 16 
169                 Sequence and Sequence-of types
170 1  -> 42  0x2a, 0100 0010 length = 42
171 
172    [
173     2  -> 2   0x2,  0000 0010 (prim) Universal id = 2, Integer type
174     3  -> 1   0x1,  0000 0001 length = 1 
175     4  -> 17  0x11, 0001 0001 integer value = 17
176    ]
177 
178    [
179     5  -> 102 0x66, 0110 0110 (const) Application id = 6
180                     LDAPv3 RFC 2251 defines APPLICATION 6 for ModifyRequests
181     6  -> 35  0x23, 0010 0011 length = 35
182        [
183            7  -> 4   0x4,  0000 0100  ( prim ) UNIVERSAL id = 4
184                            Octetstring type
185            8  -> 31  0x1f, 0001 1111  length = 31
186 
187            Octetstring = "uid=akarasulu,dc=example,dc=com"
188 
189            [117, 105, 100, 61, 97, 107, 97, 114, 97, 115, 117, 108, 117, 44, 
190             100, 99, 61, 101, 120, 97, 109, 112, 108, 101, 44, 100, 99, 61, 
191             99, 111, 109]
192 
193 
194             9  -> 117 0x75, 
195             10 -> 105 0x69, 
196             11 -> 100 0x64, 
197             12 -> 61  0x3d, 
198             13 -> 97  0x61, 
199             14 -> 107 0x6b, 
200             15 -> 97  0x61, 
201             16 -> 114 0x72, 
202             17 -> 97  0x61, 
203             18 -> 115 0x73, 
204             19 -> 117 0x75, 
205             20 -> 108 0x6c, 
206             21 -> 117 0x75, 
207             22 -> 44  0x2c, 
208             23 -> 100 0x64, 
209             24 -> 99  0x63, 
210             25 -> 61  0x3d, 
211             26 -> 101 0x65, 
212             27 -> 120 0x78, 
213             28 -> 97  0x61, 
214             29 -> 109 0x6d, 
215             30 -> 112 0x70, 
216             31 -> 108 0x6c, 
217             32 -> 101 0x65, 
218             33 -> 44  0x2c, 
219             34 -> 100 0x64, 
220             35 -> 99  0x63, 
221             36 -> 61  0x3d, 
222             37 -> 99  0x63, 
223             38 -> 111 0x6f, 
224             39 -> 109 0x6d,
225 
226 38    33    40 -> 48  0x30, 0011 0000 (const) Universal id = 16
227                             Sequence and Sequence-of types
228 39    34    41 -> 0   0x0,  length = 0
229     
230         ]
231     
232     [
233 40  42 -> -96 0xa0, 1010 0000 (prim) Context-specific id = 0
234                     "controls" part of the LDAP message Envelope
235                     is specified as context-specific [0] when no
236                     no type class name is explicitly given
237 
238         LDAPMessage ::= SEQUENCE 
239         {
240             messageID INTEGER,
241             protocolOp CHOICE { ... },
242             controls [0] Controls OPTIONAL
243         }
244 
245 41  43 -> 0   0x0   length = 0
246     ]
247 ]
248      
249      ------------------------------------------------------------------------ */
250     public void testModifyMessage() throws Exception
251     {
252         byte[] pdu = {0x30, 0x28, 0x02, 0x01, 0x11, 0x66, 0x23, 0x04, 0x1F, 0x75, 0x69, 0x64, 0x3D, 0x61, 0x6B, 0x61, 0x72, 0x61, 0x73, 0x75, 0x6C, 0x75, 0x2C, 0x64, 0x63, 0x3D, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x2C, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0x30, 0x00};
253 
254         decode( pdu ) ;
255         roundTripTest( pdu ) ;
256         assertFalse( tlvList.isEmpty() ) ;
257     }
258 
259 
260     public void testSearchMessage() throws Exception
261     {
262         byte[] pdu = {0x30, 0x27, 0x02, 0x01, 0x01, 0x63, 0x22, 0x04, 0x06, 0x64, 0x63, 0x3D, 0x63, 0x6F, 0x6D, 0x0A, 0x01, 0x00, 0x0A, 0x01, 0x03, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x00, 0xFFFFFF87, 0x07, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x30, 0x30, 0x00};
263 
264         decode( pdu ) ;
265         roundTripTest( pdu ) ;
266         assertFalse( tlvList.isEmpty() ) ;
267     }
268 }