1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 package org.apache.directory.server.kerberos.shared.messages.value;
88
89
90 import java.nio.BufferOverflowException;
91 import java.nio.ByteBuffer;
92 import java.text.ParseException;
93 import java.util.ArrayList;
94 import java.util.List;
95
96 import javax.security.auth.kerberos.KerberosPrincipal;
97
98 import org.apache.directory.server.kerberos.shared.KerberosUtils;
99 import org.apache.directory.server.kerberos.shared.messages.value.types.PrincipalNameType;
100 import org.apache.directory.shared.asn1.AbstractAsn1Object;
101 import org.apache.directory.shared.asn1.ber.tlv.TLV;
102 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
103 import org.apache.directory.shared.asn1.ber.tlv.Value;
104 import org.apache.directory.shared.asn1.codec.EncoderException;
105 import org.apache.directory.shared.ldap.util.StringTools;
106 import org.slf4j.Logger;
107 import org.slf4j.LoggerFactory;
108
109
110
111
112
113
114
115
116
117
118
119
120
121 public class PrincipalName extends AbstractAsn1Object
122 {
123
124 private static final Logger LOG = LoggerFactory.getLogger( PrincipalName.class );
125
126
127 private static final boolean IS_DEBUG = LOG.isDebugEnabled();
128
129
130 private PrincipalNameType nameType;
131
132
133 private List<String> nameString;
134
135
136 private transient List<byte[]> nameBytes;
137
138
139 private transient int principalNameSeqLength;
140 private transient int principalTypeTagLength;
141 private transient int principalTypeLength;
142 private transient int principalStringsTagLength;
143 private transient int principalStringsSeqLength;
144
145
146
147
148 public PrincipalName()
149 {
150 }
151
152
153
154
155
156
157
158
159
160 public PrincipalName( KerberosPrincipal principal )
161 {
162 try
163 {
164 nameString = KerberosUtils.getNames( principal );
165 }
166 catch ( ParseException pe )
167 {
168 nameString = KerberosUtils.EMPTY_PRINCIPAL_NAME;
169 }
170
171 this.nameType = PrincipalNameType.getTypeByOrdinal( principal.getNameType() );
172 }
173
174
175
176
177
178
179
180
181 public PrincipalName( String nameString, PrincipalNameType nameType ) throws ParseException
182 {
183 this.nameString = KerberosUtils.getNames( nameString );
184
185 this.nameType = nameType;
186 }
187
188
189
190
191
192
193
194
195 public PrincipalName( String nameString, int nameType ) throws ParseException
196 {
197 this.nameString = KerberosUtils.getNames( nameString );
198
199 this.nameType = PrincipalNameType.getTypeByOrdinal( nameType );
200 }
201
202
203
204
205
206
207
208 public PrincipalNameType getNameType()
209 {
210 return nameType;
211 }
212
213
214
215
216
217 public void setNameType( PrincipalNameType nameType )
218 {
219 this.nameType = nameType;
220 }
221
222
223
224
225
226 public void setNameType( int nameType )
227 {
228 this.nameType = PrincipalNameType.getTypeByOrdinal( nameType );
229 }
230
231
232
233
234
235
236 public List<String> getNames()
237 {
238 return nameString;
239 }
240
241
242
243
244
245 public String getNameString()
246 {
247 if ( ( nameString == null ) || ( nameString.size() == 0 ) )
248 {
249 return "";
250 }
251 else
252 {
253 StringBuilder sb = new StringBuilder();
254 boolean isFirst = true;
255
256 for ( String name : nameString )
257 {
258 if ( isFirst )
259 {
260 isFirst = false;
261 }
262 else
263 {
264 sb.append( '/' );
265 }
266
267 sb.append( name );
268 }
269
270 return sb.toString();
271 }
272 }
273
274
275
276
277
278
279 public void addName( String name )
280 {
281 if ( nameString == null )
282 {
283 nameString = new ArrayList<String>();
284 }
285
286 nameString.add( name );
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 public int computeLength()
314 {
315
316 principalTypeLength = Value.getNbBytes( nameType.getOrdinal() );
317 principalTypeTagLength = 1 + TLV.getNbBytes( principalTypeLength ) + principalTypeLength;
318
319 principalNameSeqLength = 1 + TLV.getNbBytes( principalTypeTagLength ) + principalTypeTagLength;
320
321
322 if ( ( nameString == null ) || ( nameString.size() == 0 ) )
323 {
324 principalStringsSeqLength = 0;
325 }
326 else
327 {
328 principalStringsSeqLength = 0;
329 nameBytes = new ArrayList<byte[]>( nameString.size() );
330
331 for ( String name : nameString )
332 {
333 if ( name != null )
334 {
335 byte[] bytes = StringTools.getBytesUtf8( name );
336 nameBytes.add( bytes );
337 principalStringsSeqLength += 1 + TLV.getNbBytes( bytes.length ) + bytes.length;
338 }
339 else
340 {
341 nameBytes.add( StringTools.EMPTY_BYTES );
342 principalStringsSeqLength += 1 + 1;
343 }
344 }
345 }
346
347 principalStringsTagLength = 1 + TLV.getNbBytes( principalStringsSeqLength ) + principalStringsSeqLength;
348 principalNameSeqLength += 1 + TLV.getNbBytes( principalStringsTagLength ) + principalStringsTagLength;
349
350
351 return 1 + TLV.getNbBytes( principalNameSeqLength ) + principalNameSeqLength;
352 }
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
375 {
376 if ( buffer == null )
377 {
378 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
379 }
380
381 try
382 {
383
384 buffer.put( UniversalTag.SEQUENCE_TAG );
385 buffer.put( TLV.getBytes( principalNameSeqLength ) );
386
387
388 buffer.put( ( byte ) 0xA0 );
389 buffer.put( TLV.getBytes( principalTypeTagLength ) );
390 Value.encode( buffer, nameType.getOrdinal() );
391
392
393 buffer.put( ( byte ) 0xA1 );
394 buffer.put( TLV.getBytes( principalStringsTagLength ) );
395
396
397 buffer.put( UniversalTag.SEQUENCE_TAG );
398
399 if ( ( nameString == null ) || ( nameString.size() == 0 ) )
400 {
401 buffer.put( ( byte ) 0x00 );
402 }
403 else
404 {
405 buffer.put( TLV.getBytes( principalStringsSeqLength ) );
406
407
408 for ( byte[] name : nameBytes )
409 {
410 buffer.put( UniversalTag.GENERALIZED_STRING_TAG );
411
412 if ( ( name == null ) || ( name.length == 0 ) )
413 {
414 buffer.put( ( byte ) 0x00 );
415 }
416 else
417 {
418 buffer.put( TLV.getBytes( name.length ) );
419 buffer.put( name );
420 }
421 }
422 }
423 }
424 catch ( BufferOverflowException boe )
425 {
426 LOG.error(
427 "Cannot encode the principalName object, the PDU size is {} when only {} bytes has been allocated", 1
428 + TLV.getNbBytes( principalNameSeqLength ) + principalNameSeqLength, buffer.capacity() );
429 throw new EncoderException( "The PDU buffer size is too small !" );
430 }
431
432 if ( IS_DEBUG )
433 {
434 LOG.debug( "PrinipalName encoding : {}", StringTools.dumpBytes( buffer.array() ) );
435 LOG.debug( "PrinipalName initial value : {}", toString() );
436 }
437
438 return buffer;
439 }
440
441
442
443
444
445 public String toString()
446 {
447 StringBuilder sb = new StringBuilder();
448
449 sb.append( "PincipalName : {\n" );
450
451 sb.append( " name-type: " ).append( nameType ).append( '\n' );
452
453 if ( ( nameString != null ) && ( nameString.size() != 0 ) )
454 {
455 sb.append( " name-string : <" );
456 boolean isFirst = true;
457
458 for ( String name : nameString )
459 {
460 if ( isFirst )
461 {
462 isFirst = false;
463 }
464 else
465 {
466 sb.append( ", " );
467 }
468
469 sb.append( '\'' ).append( name ).append( '\'' );
470 }
471
472 sb.append( ">\n}" );
473 }
474 else
475 {
476 sb.append( " no name-string\n}" );
477 }
478
479 return sb.toString();
480 }
481 }