1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.kerberos.credentials.cache;
21
22
23 import java.io.DataInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.nio.charset.StandardCharsets;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import org.apache.directory.shared.kerberos.KerberosTime;
31 import org.apache.directory.shared.kerberos.codec.KerberosDecoder;
32 import org.apache.directory.shared.kerberos.codec.types.AuthorizationType;
33 import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
34 import org.apache.directory.shared.kerberos.codec.types.HostAddrType;
35 import org.apache.directory.shared.kerberos.components.AuthorizationData;
36 import org.apache.directory.shared.kerberos.components.AuthorizationDataEntry;
37 import org.apache.directory.shared.kerberos.components.EncryptionKey;
38 import org.apache.directory.shared.kerberos.components.HostAddress;
39 import org.apache.directory.shared.kerberos.components.HostAddresses;
40 import org.apache.directory.shared.kerberos.components.PrincipalName;
41 import org.apache.directory.shared.kerberos.flags.TicketFlags;
42
43
44
45
46
47
48
49
50 public class CacheInputStream extends DataInputStream
51 {
52 public CacheInputStream( InputStream in )
53 {
54 super( in );
55 }
56
57
58 public void read( CredentialsCache cache ) throws IOException
59 {
60 int version;
61 List<Tag> tags;
62 PrincipalName principal;
63 Credentials cred;
64
65 version = readVersion();
66 cache.setVersion( version );
67
68 if ( version == CredentialsCacheConstants.FCC_FVNO_4 )
69 {
70 tags = readTag();
71 }
72 else
73 {
74 tags = null;
75 }
76 cache.setTags( tags );
77
78 principal = readPrincipal( version );
79 cache.setPrimaryPrincipalName( principal );
80
81 while ( available() > 0 )
82 {
83 cred = readCredentials( version );
84 if ( cred != null )
85 {
86 cache.addCredentials( cred );
87 }
88 }
89 }
90
91
92 private int readVersion() throws IOException
93 {
94 return readShort();
95 }
96
97
98 private List<Tag> readTag() throws IOException
99 {
100 int len;
101 int tag;
102 int taglen;
103 int time;
104 int usec;
105
106 len = readShort();
107 List<Tag> tags = new ArrayList<>();
108
109 while ( len > 0 )
110 {
111 tag = readShort();
112 taglen = readShort();
113
114 if ( tag == CredentialsCacheConstants.FCC_TAG_DELTATIME )
115 {
116 time = readInt();
117 usec = readInt();
118 tags.add( new Tag( tag, time, usec ) );
119 }
120 else
121 {
122 read( new byte[taglen], 0, taglen );
123 }
124
125 len = len - ( 4 + taglen );
126 }
127
128 return tags;
129 }
130
131
132 private PrincipalName readPrincipal( int version ) throws IOException
133 {
134 int type;
135 int length;
136 PrincipalName pname;
137
138 if ( version == CredentialsCacheConstants.FCC_FVNO_1 )
139 {
140 type = CredentialsCacheConstants.NT_UNKNOWN;
141 }
142 else
143 {
144 type = readInt();
145 }
146
147 length = readInt();
148
149 if ( version == CredentialsCacheConstants.FCC_FVNO_1 )
150 {
151 length--;
152 }
153
154 String realm = readCountedString();
155
156 String[] result = new String[length];
157
158 for ( int i = 0; i < length; i++ )
159 {
160 result[i] = readCountedString();
161 }
162
163 pname = new PrincipalName( result, type );
164
165 if ( isRealm( realm ) )
166 {
167 pname.setRealm( realm );
168 }
169
170 return pname;
171 }
172
173
174 private String readCountedString() throws IOException
175 {
176 int namelength = readInt();
177 if ( namelength > CredentialsCacheConstants.MAXNAMELENGTH )
178 {
179 throw new IOException( "Invalid name length in principal name." );
180 }
181 byte[] bytes = new byte[namelength];
182 read( bytes, 0, bytes.length );
183
184 return new String( bytes, StandardCharsets.UTF_8 );
185 }
186
187
188
189
190
191
192
193
194
195 private static boolean isRealm( String str )
196 {
197 char chr;
198 for ( int i = 0; i < str.length(); i++ )
199 {
200 chr = str.charAt( i );
201 if ( chr != '.' && chr >= 'a' )
202 {
203 return false;
204 }
205 }
206
207 return true;
208 }
209
210
211 private EncryptionKey readKey( int version ) throws IOException
212 {
213 int keyType;
214 int keyLen;
215 keyType = readShort();
216
217 if ( version == CredentialsCacheConstants.FCC_FVNO_3 )
218 {
219 readShort();
220 }
221
222
223 keyLen = readInt();
224 byte[] bytes = new byte[keyLen];
225 read( bytes, 0, bytes.length );
226
227 return new EncryptionKey( EncryptionType.getTypeByValue( keyType ), bytes );
228 }
229
230
231 private KerberosTime[] readKerberosTimes() throws IOException
232 {
233 long[] times = readTimes();
234 KerberosTimeberos/KerberosTime.html#KerberosTime">KerberosTime[] results = new KerberosTime[times.length];
235 KerberosTime ktime;
236
237 for ( int i = 0; i < times.length; ++i )
238 {
239 ktime = times[i] == 0 ? null : new KerberosTime( times[i] );
240 results[i] = ktime;
241 }
242
243 return results;
244 }
245
246
247 private long[] readTimes() throws IOException
248 {
249 long[] times = new long[4];
250 times[0] = ( long ) readInt() * 1000;
251 times[1] = ( long ) readInt() * 1000;
252 times[2] = ( long ) readInt() * 1000;
253 times[3] = ( long ) readInt() * 1000;
254
255 return times;
256 }
257
258
259 private boolean readskey() throws IOException
260 {
261 return read() != 0;
262 }
263
264
265 private HostAddress[] readAddr() throws IOException
266 {
267 int numAddrs;
268 int addrType;
269 int addrLength;
270 numAddrs = readInt();
271
272 if ( numAddrs > 0 )
273 {
274 HostAddresskerberos/components/HostAddress.html#HostAddress">HostAddress[] addrs = new HostAddress[numAddrs];
275
276 for ( int i = 0; i < numAddrs; i++ )
277 {
278 addrType = readShort();
279 addrLength = readInt();
280
281 if ( !( addrLength == 4 || addrLength == 16 ) )
282 {
283 return null;
284 }
285
286 byte[] result = new byte[addrLength];
287
288 for ( int j = 0; j < addrLength; j++ )
289 {
290 result[j] = readByte();
291 }
292
293 addrs[i] = new HostAddress( HostAddrType.getTypeByOrdinal( addrType ), result );
294 }
295 return addrs;
296 }
297
298 return null;
299 }
300
301
302 private AuthorizationDataEntry[] readAuth() throws IOException
303 {
304 int num;
305 int adtype;
306 int adlength;
307 num = readInt();
308
309 if ( num > 0 )
310 {
311 AuthorizationDataEntryponents/AuthorizationDataEntry.html#AuthorizationDataEntry">AuthorizationDataEntry[] auData = new AuthorizationDataEntry[num];
312 byte[] data = null;
313
314 for ( int i = 0; i < num; i++ )
315 {
316 adtype = readShort();
317 adlength = readInt();
318 data = new byte[adlength];
319 read( data, 0, data.length );
320 auData[i] = new AuthorizationDataEntry( AuthorizationType.getTypeByValue( adtype ), data );
321 }
322
323 return auData;
324 }
325
326 return null;
327 }
328
329
330 private byte[] readData() throws IOException
331 {
332 int length;
333 length = readInt();
334 if ( length == 0 )
335 {
336 return null;
337 }
338 else
339 {
340 byte[] bytes = new byte[length];
341 read( bytes, 0, length );
342 return bytes;
343 }
344 }
345
346
347 private int readFlags() throws IOException
348 {
349 int ticketFlags;
350 ticketFlags = readInt();
351 return ticketFlags;
352 }
353
354
355 private Credentials readCredentials( int version ) throws IOException
356 {
357 PrincipalName cpname = readPrincipal( version );
358 PrincipalName spname = readPrincipal( version );
359
360 EncryptionKey key = readKey( version );
361
362 KerberosTime[] times = readKerberosTimes();
363 KerberosTime authtime = times[0];
364 KerberosTime starttime = times[1];
365 KerberosTime endtime = times[2];
366 KerberosTime renewTill = times[3];
367
368 boolean skey = readskey();
369
370 int flags = readFlags();
371 TicketFlags/kerberos/flags/TicketFlags.html#TicketFlags">TicketFlags tFlags = new TicketFlags( flags );
372 HostAddress addr[] = readAddr();
373 HostAddresses addrs = null;
374
375 if ( addr != null )
376 {
377 addrs = new HostAddresses( addr );
378 }
379
380 AuthorizationDataEntry[] auDataEntries = readAuth();
381 AuthorizationData auData = null;
382
383 if ( auDataEntries != null )
384 {
385 auData = new AuthorizationData();
386
387 for ( AuthorizationDataEntry ade : auDataEntries )
388 {
389 auData.addEntry( ade );
390 }
391 }
392
393 byte[] ticketData = readData();
394 byte[] ticketData2 = readData();
395
396 if ( version != CredentialsCacheConstants.FCC_FVNO_1 &&
397 spname.getNameType().getValue() == CredentialsCacheConstants.NT_UNKNOWN )
398 {
399
400 return null;
401 }
402
403 try
404 {
405 return new Credentials( cpname, spname, key, authtime, starttime,
406 endtime, renewTill, skey, tFlags, addrs, auData,
407 ticketData != null ? KerberosDecoder.decodeTicket( ticketData ) : null,
408 ticketData2 != null ? KerberosDecoder.decodeTicket( ticketData2 ) : null );
409 }
410 catch ( Exception e )
411 {
412 return null;
413 }
414 }
415 }