1 |
#!/usr/bin/env python2 |
2 |
|
3 |
import string |
4 |
import getopt |
5 |
import sys |
6 |
import time |
7 |
import re |
8 |
import POW |
9 |
import struct |
10 |
import os |
11 |
|
12 |
from keymap import keymap |
13 |
|
14 |
keys = keymap("keymaps", 'sv') |
15 |
currentchannel = 0 |
16 |
|
17 |
rdp_channel_flags = [(0x80000000, "OPTION_INITIALIZED"), |
18 |
(1073741824, "OPTION_ENCRYPT_RDP"), |
19 |
(536870912, "OPTION_ENCRYPT_SC"), |
20 |
(268435456, "OPTION_ENCRYPT_CS"), |
21 |
(134217728, "OPTION_PRI_HIGH"), |
22 |
(67108864, "OPTION_PRI_MED"), |
23 |
(33554432, "OPTION_PRI_LOW"), |
24 |
(8388608, "OPTION_COMPRESS_RDP"), |
25 |
(4194304, "OPTION_COMPRESS"), |
26 |
(2097152, "OPTION_SHOW_PROTOCOL")] |
27 |
|
28 |
rdp_channels = {} |
29 |
|
30 |
def LaTeX_escape(s): |
31 |
s = s.replace("#", "\\#") |
32 |
s = s.replace("_", "\\_") |
33 |
return s |
34 |
|
35 |
class PacketPart: |
36 |
BER_TAGS = {'BOOLEAN':1, |
37 |
'INTEGER':2, |
38 |
'OCTET_STRING':4, |
39 |
'TAG_RESULT':10, |
40 |
'DOMAIN_PARAMS':0x30, |
41 |
'CONN_INITIAL':0x7f65, |
42 |
'CONN_RESPONSE':0x7f66} |
43 |
|
44 |
classname = "PacketPart" |
45 |
|
46 |
def __init__(self, description, knvalue=None, indent=0, **kw): |
47 |
self.description = description |
48 |
self.owntbl = 1 |
49 |
self.knvalue = knvalue |
50 |
self.indent = indent |
51 |
self.datatype = "[unknown type]" |
52 |
self.value = [] |
53 |
self.raw = 0 |
54 |
self.maxlength = 0 |
55 |
|
56 |
if kw.has_key('maxlength'): |
57 |
self.maxlength = kw['maxlength'] |
58 |
else: |
59 |
self.maxlength = None |
60 |
|
61 |
def __len__(self): |
62 |
ret = 0 |
63 |
for p in self.value: |
64 |
ret+=len(p) |
65 |
return ret |
66 |
|
67 |
def strvalue(self): |
68 |
if 0 == len(self.value): |
69 |
return "[no value]" |
70 |
else: |
71 |
ret = "\n"+" "*self.indent |
72 |
ret+=string.join(map(lambda x: str(x), |
73 |
self.value), |
74 |
"\n"+" "*self.indent) |
75 |
return ret |
76 |
|
77 |
def tblvalue(self, **kw): |
78 |
s = "%s\t%s\t" % (self.datatype, |
79 |
self.description) |
80 |
if None != self.knvalue: |
81 |
s+=str(self.knvalue) |
82 |
s+="\t%s\t" % self.strvalue() |
83 |
return s |
84 |
|
85 |
def latexvalue(self, **kw): |
86 |
s = "%s & %s &" % (self.datatype, self.description) |
87 |
if None != self.knvalue: |
88 |
s+=str(self.knvalue) |
89 |
s+="& %s \\\\ \n" % self.strvalue() |
90 |
return s |
91 |
|
92 |
def __str__(self): |
93 |
ret = " "*self.indent+self.datatype+" "+self.description+" " |
94 |
if None != self.knvalue: |
95 |
ret+="(expected: "+str(self.knvalue)+") " |
96 |
if self.raw: |
97 |
ret+=" RAW DATA (length 0x%.2x (%d))" % (self.rawlength, |
98 |
self.rawlength) |
99 |
return ret+self.strvalue() |
100 |
|
101 |
def hextostr(self, data, fill=1): |
102 |
ret = "" |
103 |
if fill and len(data) < 16: |
104 |
ret+=(16-len(data))*" " |
105 |
for c in data: |
106 |
if c >= 0x20 and c < 0x7f: |
107 |
ret+=chr(c) |
108 |
else: |
109 |
ret+="." |
110 |
return ret |
111 |
|
112 |
def packtobytestring(self, data): |
113 |
ret = "" |
114 |
for byte in data: |
115 |
ret+=struct.pack('B', byte) |
116 |
return ret |
117 |
|
118 |
def parse(self, data): |
119 |
"""Parse the packet value into a human readable form. |
120 |
In PacketPart (top-level class), we just eat the bytes and |
121 |
present it as a hexdump, as a last resort""" |
122 |
|
123 |
returndata = [] |
124 |
if None != self.maxlength: |
125 |
returndata = data[self.maxlength:] |
126 |
data = data[:self.maxlength] |
127 |
|
128 |
self.raw = 1 |
129 |
self.rawlength = len(data) |
130 |
|
131 |
while 0 < len(data): |
132 |
hl = HexLine("") |
133 |
data = hl.parse(data) |
134 |
self.value.append(hl) |
135 |
|
136 |
return returndata |
137 |
|
138 |
def postparse(self, data): |
139 |
return data |
140 |
|
141 |
def preparse(self, data): |
142 |
return data |
143 |
|
144 |
def ppparse(self, data): |
145 |
return self.postparse(self.parse(self.preparse(data))) |
146 |
|
147 |
class CryptoSignature(PacketPart): |
148 |
def __init__(self, description, **kw): |
149 |
PacketPart.__init__(self, description, **kw) |
150 |
self.owntbl = 0 |
151 |
|
152 |
def latexvalue(self, **kw): |
153 |
return "RAW & Crypto signature & & 8 bytes of data\\\\" |
154 |
|
155 |
class HexLine(PacketPart): |
156 |
|
157 |
classname = "HexLine" |
158 |
|
159 |
def __init__(self, description, **kw): |
160 |
PacketPart.__init__(self, description, **kw) |
161 |
self.datatype="RAW" |
162 |
self.owntbl = 0 |
163 |
|
164 |
def parse(self, data): |
165 |
self.value = data[:16] |
166 |
return data[16:] |
167 |
|
168 |
def strvalue(self): |
169 |
datap = map(lambda x: "%.2x" % x, self.value) |
170 |
return string.join(datap, ' ')+" "+self.hextostr(self.value) |
171 |
|
172 |
def tblvalue(self, **kw): |
173 |
return "RAW\t%s\t\t%s\t%s" % (self.description, string.join( |
174 |
map(lambda x: "%.2x" % x, self.value), " "), |
175 |
self.hextostr(self.value, fill=0)) |
176 |
|
177 |
def tblvalue(self, **kw): |
178 |
return "RAW & %s& & %s & %s \\\n" % (self.description, string.join( |
179 |
map(lambda x: "%.2x" % x, self.value), " "), |
180 |
self.hextostr(self.value, fill=0)) |
181 |
|
182 |
|
183 |
|
184 |
|
185 |
def __len__(self): |
186 |
return len(self.value) |
187 |
|
188 |
|
189 |
class Integer8Part(PacketPart): |
190 |
|
191 |
classname = "Integer8Part" |
192 |
|
193 |
def __init__(self, description, **kw): |
194 |
PacketPart.__init__(self, description, **kw) |
195 |
self.datatype="Int8 (be)" |
196 |
self.value = -1 |
197 |
self.owntbl = 0 |
198 |
|
199 |
def __len__(self): |
200 |
return 1 |
201 |
|
202 |
def strvalue(self): |
203 |
return "0x%.2x (%d)" % (self.value, self.value) |
204 |
|
205 |
def parse(self, data): |
206 |
self.value = data[0] |
207 |
return data[1:] |
208 |
|
209 |
class Integer16Part(Integer8Part): |
210 |
|
211 |
classname = "Integer16Part" |
212 |
|
213 |
def __init__(self, description, **kw): |
214 |
Integer8Part.__init__(self, description, **kw) |
215 |
self.datatype="Int16 (be)" |
216 |
|
217 |
def __len__(self): |
218 |
return 2 |
219 |
|
220 |
def strvalue(self): |
221 |
return "0x%.4x (%d)" % (self.value, self.value) |
222 |
|
223 |
def parse(self, data): |
224 |
try: |
225 |
self.value = string.atoi(string.join(map(lambda x: "%.2x" % x, |
226 |
data[0:2]), ''), 16) |
227 |
except ValueError: |
228 |
print "Exception while parsing %s:" % self.description |
229 |
raise |
230 |
return data[2:] |
231 |
|
232 |
class Integer16or8000Part(Integer16Part): |
233 |
|
234 |
classname = "Integer16or8000Part" |
235 |
|
236 |
def parse(self, data): |
237 |
data = Integer16Part.parse(self, data) |
238 |
self.value = self.value & ~0x8000 |
239 |
self.datatype = "Int16 (be) | 0x8000" |
240 |
return data |
241 |
|
242 |
class Integer16lePart(Integer16Part): |
243 |
|
244 |
classname = "Integer16lePart" |
245 |
|
246 |
def __init__(self, description, **kw): |
247 |
Integer8Part.__init__(self, description, **kw) |
248 |
self.datatype="Int16 (le)" |
249 |
|
250 |
def parse(self, data): |
251 |
mydata = data[0:2] |
252 |
mydata.reverse() |
253 |
Integer16Part.parse(self, mydata) |
254 |
return data[2:] |
255 |
|
256 |
class Integer32Part(Integer8Part): |
257 |
|
258 |
classname = "Integer32Part" |
259 |
|
260 |
def __init__(self, description, **kw): |
261 |
Integer8Part.__init__(self, description, **kw) |
262 |
self.datatype="Int32 (be)" |
263 |
|
264 |
def __len__(self): |
265 |
return 4 |
266 |
|
267 |
def strvalue(self): |
268 |
return "0x%.8x (%d)" % (self.value, self.value) |
269 |
|
270 |
def parse(self, data): |
271 |
valstr = string.join(map(lambda x: "%.2x" % x, data[:4]), '') |
272 |
try: |
273 |
self.value = string.atoi(valstr, 16) |
274 |
except ValueError: |
275 |
self.value = string.atol(valstr, 16) |
276 |
return data[4:] |
277 |
|
278 |
class Integer32lePart(Integer32Part): |
279 |
|
280 |
classname = "Integer32lePart" |
281 |
|
282 |
def __init__(self, description, **kw): |
283 |
Integer32Part.__init__(self, description, **kw) |
284 |
self.datatype="Int32 (le)" |
285 |
|
286 |
def parse(self, data): |
287 |
mydata = data[0:4] |
288 |
mydata.reverse() |
289 |
Integer32Part.parse(self, mydata) |
290 |
return data[4:] |
291 |
|
292 |
class Time32le(Integer32lePart): |
293 |
|
294 |
classname = "Time32le" |
295 |
|
296 |
def __init__(self, description, **kw): |
297 |
Integer32lePart.__init__(self, description, **kw) |
298 |
self.datatype="Time" |
299 |
|
300 |
def strvalue(self): |
301 |
return Integer32Part.strvalue(self)+\ |
302 |
" (%s)" % time.asctime(time.gmtime(self.value)) |
303 |
|
304 |
|
305 |
class VariableInt(PacketPart): |
306 |
|
307 |
classname = "VariableInt" |
308 |
|
309 |
def __init__(self, description, **kw): |
310 |
PacketPart.__init__(self, description, **kw) |
311 |
self.owntbl = 0 |
312 |
|
313 |
def parse(self, data): |
314 |
self.value = data[0] |
315 |
data = data[1:] |
316 |
self.datatype = "VariableInt(1)" |
317 |
self.lengthbytes = 0 |
318 |
if self.value & 0x80: |
319 |
self.lengthbytes = self.value & ~0x80 |
320 |
self.datatype = "VariableInt(%d)" % self.lengthbytes |
321 |
self.value = string.atoi(string.join(map(lambda x: "%.2x" % x, |
322 |
data[0:self.lengthbytes]), |
323 |
''), 16) |
324 |
data = data[self.lengthbytes:] |
325 |
|
326 |
return data |
327 |
|
328 |
def __len__(self): |
329 |
return self.lengthbytes+1 |
330 |
|
331 |
def strvalue(self): |
332 |
return "0x%.4x (%d)" % (self.value, self.value) |
333 |
|
334 |
class MSVariableInt(VariableInt): |
335 |
|
336 |
classname = "MSVariableInt" |
337 |
|
338 |
def parse(self, data): |
339 |
self.value = data[0] |
340 |
data = data[1:] |
341 |
self.datatype = "MSVariableInt(1)" |
342 |
self.lengthbytes = 1 |
343 |
|
344 |
if self.value & 0x80: |
345 |
self.lengthbytes = 2 |
346 |
lb = data[0] |
347 |
data = data[1:] |
348 |
self.value = ((self.value & ~0x80) << 8) | lb |
349 |
self.datatype = "MSVariableInt(2)" |
350 |
|
351 |
|
352 |
return data |
353 |
|
354 |
class KnownLengthInt(PacketPart): |
355 |
|
356 |
classname = "KnownLengthInt" |
357 |
|
358 |
def __init__(self, description, length, **kw): |
359 |
PacketPart.__init__(self, description, **kw) |
360 |
self.length = length |
361 |
self.datatype = "KLIInt(%d)" % (8*length) |
362 |
self.owntbl = 0 |
363 |
|
364 |
def strvalue(self): |
365 |
return "0x%.2x (%d)" % (self.value, self.value) |
366 |
|
367 |
def parse(self, data): |
368 |
self.value = string.atoi(string.join(map(lambda x: "%.2x" % x, |
369 |
data[0:self.length]), |
370 |
''), 16) |
371 |
return data[self.length:] |
372 |
|
373 |
def __len__(self): |
374 |
return self.length |
375 |
|
376 |
|
377 |
class MultiTableValue(PacketPart): |
378 |
|
379 |
classname = "MultiTableValue" |
380 |
|
381 |
def tblvalue(self, offset=0): |
382 |
s = "%s\n" % self.value[0].tblvalue(offset=offset) |
383 |
offset+=len(self.value[0]) |
384 |
for part in self.value[1:-1]: |
385 |
s+="%d\t%s\n" % (offset, part.tblvalue(offset=offset)) |
386 |
offset+=len(part) |
387 |
s+="%d\t%s" % (offset, self.value[-1:][0].tblvalue(offset=offset)) |
388 |
return s |
389 |
|
390 |
def latexvalue(self, offset=0): |
391 |
s = "%s\n" % self.value[0].latexvalue(offset=offset) |
392 |
offset+=len(self.value[0]) |
393 |
for part in self.value[1:-1]: |
394 |
s+="%d & %s\n" % (offset, part.latexvalue(offset=offset)) |
395 |
offset+=len(part) |
396 |
s+="%d & %s\\\\" % (offset, |
397 |
self.value[-1:][0].latexvalue(offset=offset)) |
398 |
return s |
399 |
|
400 |
|
401 |
class BERHeader(PacketPart): |
402 |
|
403 |
classname = "BERHeader" |
404 |
|
405 |
def __init__(self, description, tag, **kw): |
406 |
PacketPart.__init__(self, description, **kw) |
407 |
self.tag = tag |
408 |
self.owntbl = 0 |
409 |
self.taglen = 1 |
410 |
|
411 |
def parse(self, data): |
412 |
if self.tag > 0xff: |
413 |
self.taglen = 2 |
414 |
self.realtag = string.atoi(string.join(map(lambda x: "%.2x" % x, |
415 |
data[0:2]), ''), 16) |
416 |
|
417 |
self.datatype = "BER tag %d" % (self.realtag) |
418 |
|
419 |
if self.realtag != self.tag: |
420 |
raise "Unexpected BER tag, "\ |
421 |
"got %s expected %s" % (str(self.value), |
422 |
str(self.tag)) |
423 |
|
424 |
data = data[2:] |
425 |
|
426 |
else: |
427 |
self.realtag = data[0] |
428 |
|
429 |
self.datatype = "BER tag %d" % (self.realtag) |
430 |
|
431 |
if self.realtag != self.tag: |
432 |
raise "Unexpected BER tag, "\ |
433 |
"got %s expected %s" % (str(self.value), str(self.tag)) |
434 |
|
435 |
data = data[1:] |
436 |
|
437 |
length = VariableInt("BER length", indent=self.indent+1) |
438 |
self.value.append(length) |
439 |
return length.parse(data) |
440 |
|
441 |
def __len__(self): |
442 |
return self.taglen + len(self.value[0]) |
443 |
|
444 |
def tblvalue(self, offset=0): |
445 |
s = "%s\t%s\t%s\t%s\n" % (self.datatype, self.description, |
446 |
self.tag, self.realtag) |
447 |
return s+"%d\t%s" % (offset+self.taglen, |
448 |
self.value[0].tblvalue(offset=offset+self.taglen)) |
449 |
|
450 |
def latexvalue(self, offset=0): |
451 |
s = "%s & %s & %s & %s \\\\" % (self.datatype, self.description, |
452 |
self.tag, self.realtag) |
453 |
return s+"%d & %s" % (offset+self.taglen, |
454 |
self.value[0].latexvalue(offset=offset+self.taglen)) |
455 |
|
456 |
|
457 |
|
458 |
|
459 |
class BERValue(MultiTableValue): |
460 |
|
461 |
classname = "BERValue" |
462 |
|
463 |
def __init__(self, description, bertype, **kw): |
464 |
PacketPart.__init__(self, description, **kw) |
465 |
self.bertype = bertype |
466 |
self.owntbl = 0 |
467 |
|
468 |
def parse(self, data): |
469 |
hdr = BERHeader(self.bertype, self.BER_TAGS[self.bertype], |
470 |
indent=self.indent+1) |
471 |
self.value.append(hdr) |
472 |
data = hdr.parse(data) |
473 |
|
474 |
self.datatype = "BER %s(%d)" % (self.bertype, |
475 |
8*hdr.value[0].value) |
476 |
|
477 |
|
478 |
kliint = KnownLengthInt(self.description + " Value", |
479 |
hdr.value[0].value, |
480 |
indent=self.indent+1) |
481 |
self.value.append(kliint) |
482 |
return kliint.parse(data) |
483 |
|
484 |
|
485 |
class DomainParametersPacket(PacketPart): |
486 |
|
487 |
classname = "DomainParametersPacket" |
488 |
|
489 |
def __init__(self, description, **kw): |
490 |
PacketPart.__init__(self, description, **kw) |
491 |
self.datatype = "Domain Parameters" |
492 |
|
493 |
def parse(self, data): |
494 |
domparam_initial_header = BERHeader(self.description, |
495 |
self.BER_TAGS['DOMAIN_PARAMS'], |
496 |
indent=self.indent) |
497 |
self.value.append(domparam_initial_header) |
498 |
|
499 |
self.value.append(BERValue("Channels", 'INTEGER', |
500 |
indent=self.indent+1)) |
501 |
self.value.append(BERValue("Users", 'INTEGER', |
502 |
indent=self.indent+1)) |
503 |
self.value.append(BERValue("Tokens", 'INTEGER', |
504 |
indent=self.indent+1)) |
505 |
self.value.append(BERValue("Priorities", 'INTEGER', |
506 |
indent=self.indent+1)) |
507 |
self.value.append(BERValue("Throughput", 'INTEGER', |
508 |
indent=self.indent+1)) |
509 |
self.value.append(BERValue("Height", 'INTEGER', indent=self.indent+1)) |
510 |
self.value.append(BERValue("PDUsize", 'INTEGER', indent=self.indent+1)) |
511 |
self.value.append(BERValue("Protocol", 'INTEGER', |
512 |
indent=self.indent+1)) |
513 |
|
514 |
for dp in self.value: |
515 |
data = dp.parse(data) |
516 |
|
517 |
return data |
518 |
|
519 |
class Latin1String(PacketPart): |
520 |
classname = "Latin1String" |
521 |
|
522 |
def __init__(self, description, length, **kw): |
523 |
PacketPart.__init__(self, description, **kw) |
524 |
self.havenullchar=1 |
525 |
if kw.has_key("nonullchar"): |
526 |
self.havenullchar=0 |
527 |
self.datatype = "Latin1 String(%d" % length |
528 |
if self.havenullchar: |
529 |
self.datatype+=" + nullchar)" |
530 |
else: |
531 |
self.datatype+=")" |
532 |
self.length = length |
533 |
self.owntbl = 0 |
534 |
|
535 |
|
536 |
|
537 |
def __len__(self): |
538 |
return self.length + self.havenullchar |
539 |
|
540 |
def strvalue(self): |
541 |
return self.value |
542 |
|
543 |
def parse(self, data): |
544 |
self.value = "" |
545 |
mydata = data[0:self.length] |
546 |
for char in mydata: |
547 |
if char != 0: |
548 |
self.value+=(chr(char)) |
549 |
|
550 |
return data[self.length+self.havenullchar:] |
551 |
|
552 |
class UnicodeString(PacketPart): |
553 |
|
554 |
classname = "UnicodeString" |
555 |
|
556 |
def __init__(self, description, length, **kw): |
557 |
PacketPart.__init__(self, description, **kw) |
558 |
self.datatype = "Unicode string(%d)" % length |
559 |
self.length = length |
560 |
self.owntbl = 0 |
561 |
|
562 |
def __len__(self): |
563 |
return self.length |
564 |
|
565 |
def strvalue(self): |
566 |
return self.value |
567 |
|
568 |
def parse(self, data): |
569 |
self.value = "" |
570 |
mydata = data[0:2*self.length] |
571 |
while 0 < len(mydata): |
572 |
thischr = mydata[0:2] |
573 |
thischr.reverse() |
574 |
val = string.atoi(string.join(map(lambda x: "%.2x" % x, |
575 |
thischr), ''), 16) |
576 |
if val in range(1, 256): |
577 |
self.value+=unichr(val).encode('latin-1') |
578 |
elif 0 == val: |
579 |
self.value+="." |
580 |
else: |
581 |
self.value+="§" |
582 |
mydata = mydata[2:] |
583 |
|
584 |
return data[2*self.length:] |
585 |
|
586 |
class ColorDepthInfo(Integer16lePart): |
587 |
|
588 |
classname = "ColorDepthInfo" |
589 |
|
590 |
depths = {0xca01:'8', |
591 |
0xca02:'15', |
592 |
0xca03:'16', |
593 |
0xca04:'24'} |
594 |
|
595 |
def __init__(self, description, **kw): |
596 |
Integer16lePart.__init__(self, description, **kw) |
597 |
self.datatype = "ColorDepth (Int16 (le))" |
598 |
|
599 |
def strvalue(self): |
600 |
return Integer16lePart.strvalue(self) + "(%s bits depth)" % self.depths.get(self.value, "Unknown") |
601 |
|
602 |
|
603 |
class UserdataClientinfoPacket(PacketPart): |
604 |
|
605 |
classname = "UserdataClientinfoPacket" |
606 |
|
607 |
def __init__(self, description, **kw): |
608 |
PacketPart.__init__(self, description, **kw) |
609 |
self.datatype = "MCS userdata/clientinfo" |
610 |
|
611 |
def parse(self, data): |
612 |
clinfotag = Integer16lePart("Client info tag", knvalue=0xc001, |
613 |
indent=self.indent) |
614 |
self.value.append(clinfotag) |
615 |
data = clinfotag.parse(data) |
616 |
|
617 |
if clinfotag.value != 0xc001: |
618 |
raise "Expected Client info (tagged by 0xc001), got %d" % clinfotag.value |
619 |
|
620 |
clinfolen = Integer16lePart("Client info length", |
621 |
knvalue="136 in rdesktop, "\ |
622 |
"%d bytes remaining" % (len(data)-2), |
623 |
indent=self.indent) |
624 |
self.value.append(clinfolen) |
625 |
data = clinfolen.parse(data) |
626 |
|
627 |
clinfodata = data[:clinfolen.value-4] |
628 |
|
629 |
self.value.append(Integer16lePart("RDP version", |
630 |
knvalue="0x0001 for RDP4, "\ |
631 |
"0x0004 for RDP5", |
632 |
indent=self.indent)) |
633 |
self.value.append(Integer16lePart("", knvalue=0x0008, |
634 |
indent=self.indent)) |
635 |
self.value.append(Integer16lePart("Width", |
636 |
indent=self.indent)) |
637 |
self.value.append(Integer16lePart("Height", |
638 |
indent=self.indent)) |
639 |
self.value.append(Integer16lePart("", knvalue=0xca01, |
640 |
indent=self.indent)) |
641 |
self.value.append(Integer16lePart("", knvalue=0xaa03, |
642 |
indent=self.indent)) |
643 |
self.value.append(Integer32lePart("Keylayout", |
644 |
indent=self.indent)) |
645 |
self.value.append(Integer32lePart("Client build", |
646 |
indent=self.indent)) |
647 |
self.value.append(UnicodeString("Hostname", 16, |
648 |
indent=self.indent)) |
649 |
self.value.append(Integer32lePart("", knvalue=0x00000004, |
650 |
indent=self.indent)) |
651 |
self.value.append(Integer32lePart("", knvalue=0x00000000, |
652 |
indent=self.indent)) |
653 |
self.value.append(Integer32lePart("", knvalue=0x0000000c, |
654 |
indent=self.indent)) |
655 |
|
656 |
valuelen = len(self.value) |
657 |
|
658 |
for dp in self.value[2:]: |
659 |
clinfodata = dp.parse(clinfodata) |
660 |
|
661 |
reserved_data = PacketPart("Reserved data", indent=self.indent) |
662 |
self.value.append(reserved_data) |
663 |
reserved_data.parse(clinfodata[:64]) |
664 |
valuelen+=1 |
665 |
|
666 |
clinfodata = clinfodata[64:] |
667 |
|
668 |
self.value.append(ColorDepthInfo("(client)", indent=self.indent)) |
669 |
|
670 |
self.value.append(Integer16lePart("", knvalue=0x0000, |
671 |
indent=self.indent)) |
672 |
|
673 |
self.value.append(PacketPart("Remaining client data", |
674 |
indent=self.indent)) |
675 |
|
676 |
for dp in self.value[valuelen:]: |
677 |
clinfodata = dp.parse(clinfodata) |
678 |
|
679 |
return data[clinfolen.value-4:] |
680 |
|
681 |
class CertificatePart(PacketPart): |
682 |
|
683 |
classname = "CertificatePart" |
684 |
|
685 |
def __init__(self, description, **kw): |
686 |
PacketPart.__init__(self, description, **kw) |
687 |
self.datatype = "Certificate" |
688 |
|
689 |
def parse(self, data): |
690 |
returndata = [] |
691 |
if None != self.maxlength: |
692 |
returndata = data[self.maxlength:] |
693 |
data = data[:self.maxlength] |
694 |
|
695 |
strcert = self.packtobytestring(data) |
696 |
x = POW.derRead(POW.X509_CERTIFICATE, strcert) |
697 |
self.value = [x.pprint().replace("\\x00", "")] |
698 |
|
699 |
return returndata |
700 |
|
701 |
def latexvalue(self, **kw): |
702 |
return "\\begin{verbatim}\n%s\n\\end{verbatim}" % self.value |
703 |
|
704 |
class MCSResponseCryptinfoPacket(PacketPart): |
705 |
|
706 |
classname = "MCSResponseCryptinfoPacket" |
707 |
|
708 |
def __init__(self, description, **kw): |
709 |
PacketPart.__init__(self, description, **kw) |
710 |
self.datatype = "MCS response userdata cryptinfo" |
711 |
|
712 |
def parse(self, data): |
713 |
self.value.append(Integer32lePart("RC4 key size", indent=self.indent, |
714 |
knvalue="1/40 bit, 2/128 bit")) |
715 |
self.value.append(Integer32lePart("Encryption level", |
716 |
indent=self.indent, |
717 |
knvalue="0/None, 1/Low, 2/Med, 3/High")) |
718 |
randsaltlen = Integer32lePart("Random salt len", |
719 |
indent=self.indent, |
720 |
knvalue=0x20) |
721 |
self.value.append(randsaltlen) |
722 |
|
723 |
for dp in self.value: |
724 |
data = dp.parse(data) |
725 |
|
726 |
valuelen = len(self.value) |
727 |
|
728 |
self.value.append(Integer32lePart("RSA info len", |
729 |
indent=self.indent, |
730 |
knvalue=len(data)-32-4)) |
731 |
|
732 |
for dp in self.value[valuelen:]: |
733 |
data = dp.parse(data) |
734 |
|
735 |
valuelen = len(self.value) |
736 |
|
737 |
self.value.append(PacketPart("Server salt", indent=self.indent, maxlength=randsaltlen.value)) |
738 |
|
739 |
self.value.append(PacketPart("Cert header", indent=self.indent, maxlength=8)) |
740 |
cacertlen = Integer32lePart("CA Certificate length", indent=self.indent) |
741 |
self.value.append(cacertlen) |
742 |
|
743 |
for dp in self.value[valuelen:]: |
744 |
data = dp.parse(data) |
745 |
|
746 |
valuelen = len(self.value) |
747 |
|
748 |
self.value.append(CertificatePart("(CA)", indent=self.indent, |
749 |
maxlength=cacertlen.value)) |
750 |
certlen = Integer32lePart("Certificate length", indent=self.indent) |
751 |
self.value.append(certlen) |
752 |
|
753 |
for dp in self.value[valuelen:]: |
754 |
data = dp.parse(data) |
755 |
|
756 |
valuelen = len(self.value) |
757 |
|
758 |
self.value.append(CertificatePart("", indent=self.indent, maxlength=certlen.value)) |
759 |
self.value.append(PacketPart("Remaining info", indent=self.indent)) |
760 |
|
761 |
for dp in self.value[valuelen:]: |
762 |
data = dp.parse(data) |
763 |
|
764 |
return data |
765 |
|
766 |
class SrvInfoPart(PacketPart): |
767 |
|
768 |
classname = "Srvinfopart" |
769 |
|
770 |
def __init__(self, description, **kw): |
771 |
PacketPart.__init__(self, description, **kw) |
772 |
self.datatype = "TAG_SRV_INFO" |
773 |
|
774 |
def parse(self, data): |
775 |
self.value.append(Integer16lePart("RDP version", |
776 |
indent=self.indent+1)) |
777 |
self.value.append(Integer16lePart("Unknown", |
778 |
indent=self.indent+1, |
779 |
knvalue=8)) |
780 |
|
781 |
for dp in self.value: |
782 |
data = dp.parse(data) |
783 |
|
784 |
return data |
785 |
|
786 |
class TaggedData(PacketPart): |
787 |
|
788 |
classname = "TaggedData" |
789 |
|
790 |
class HexLines(PacketPart): |
791 |
classname = "HexLines" |
792 |
def tblvalue(self, offset=0): |
793 |
s = self.value[0].tblvalue()+"\n" |
794 |
offset+=len(self.value[0]) |
795 |
for hexline in self.value[1:]: |
796 |
s+="%d\t%s\n" % (offset, hexline.tblvalue()) |
797 |
offset+=len(hexline) |
798 |
return s |
799 |
|
800 |
def latexvalue(self, offset=0): |
801 |
s = self.value[0].latexvalue()+"\n" |
802 |
offset+=len(self.value[0]) |
803 |
for hexline in self.value[1:]: |
804 |
s+="%d & %s\\\\\n" % (offset, hexline.latexvalue()) |
805 |
offset+=len(hexline) |
806 |
return s |
807 |
|
808 |
class CliChannelsPart(PacketPart): |
809 |
classname = "CliChannelsPart" |
810 |
class ChannelFlags(Integer32lePart): |
811 |
|
812 |
classname = "ChannelFlags" |
813 |
|
814 |
def __init__(self, description, **kw): |
815 |
PacketPart.__init__(self, description, **kw) |
816 |
self.datatype = "RDP Channel Flags" |
817 |
self.owntbl = 0 |
818 |
|
819 |
def strvalue(self): |
820 |
ret = Integer32lePart.strvalue(self)+" " |
821 |
for flag, desc in rdp_channel_flags: |
822 |
if self.value & flag: |
823 |
ret+="%s, " % desc |
824 |
|
825 |
return ret |
826 |
|
827 |
def __init__(self, description, **kw): |
828 |
PacketPart.__init__(self, description, **kw) |
829 |
self.datatype = "RDP Channel data" |
830 |
self.owntbl = 1 |
831 |
|
832 |
def parse(self, data): |
833 |
numchannels = Integer32lePart("Number of channels", indent=self.indent+1) |
834 |
self.value.append(numchannels) |
835 |
data = numchannels.parse(data) |
836 |
|
837 |
for i in range(numchannels.value): |
838 |
channelname = Latin1String("Channel #%d name" % i, 7, indent=self.indent+2) |
839 |
channelflags = self.ChannelFlags("Channel #%d flags" % i, indent=self.indent+2) |
840 |
self.value.append(channelname) |
841 |
self.value.append(channelflags) |
842 |
data = channelname.parse(data) |
843 |
data = channelflags.parse(data) |
844 |
|
845 |
rdp_channels[i] = (channelname.value, channelflags.value) |
846 |
|
847 |
return data |
848 |
|
849 |
|
850 |
|
851 |
|
852 |
tags = {0xc001:('TAG_CLI_INFO', HexLines), |
853 |
0xc002:('TAG_CLI_CRYPT', HexLines), |
854 |
0xc003:('TAG_CLI_CHANNELS', CliChannelsPart), |
855 |
0x0c01:('TAG_SRV_INFO', SrvInfoPart), |
856 |
0x0c02:('TAG_SRV_CRYPT', MCSResponseCryptinfoPacket), |
857 |
0x0c03:('TAG_SRV_SRV3', HexLines)} |
858 |
|
859 |
def __init__(self, description, **kw): |
860 |
PacketPart.__init__(self, description, **kw) |
861 |
self.datatype = "Tagged data" |
862 |
self.owntbl = 1 |
863 |
|
864 |
def parse(self, data): |
865 |
|
866 |
while 0 < len(data): |
867 |
|
868 |
tag = Integer16lePart("Tag", indent=self.indent+2) |
869 |
data = tag.parse(data) |
870 |
|
871 |
length = Integer16lePart("Length", indent=self.indent+2) |
872 |
data = length.parse(data) |
873 |
|
874 |
(tagtype, packetclass) = self.tags.get(tag.value, |
875 |
("Unknown", self.HexLines)) |
876 |
|
877 |
datapart = packetclass("Data", indent=self.indent+2) |
878 |
packetdata = data[:length.value-4] |
879 |
datapart.parse(packetdata) |
880 |
|
881 |
container = PacketPart("%s" % tagtype, |
882 |
indent=self.indent+1) |
883 |
container.datatype = "Tagged datapart" |
884 |
container.value.append(tag) |
885 |
container.value.append(length) |
886 |
container.value.append(datapart) |
887 |
|
888 |
self.value.append(container) |
889 |
|
890 |
data = data[length.value-4:] |
891 |
|
892 |
return data # Should return empty list. |
893 |
|
894 |
def tblvalue(self, offset=0): |
895 |
tag = self.value[0].value[0] |
896 |
length = self.value[0].value[1] |
897 |
dp = self.value[0].value[2] |
898 |
(tagtype, packetclass) = self.tags.get(tag.value, |
899 |
("Unknown", PacketPart)) |
900 |
|
901 |
s = "%s\tTag\t\t%s (%s)\n" % (tag.datatype, |
902 |
tag.value, tagtype) |
903 |
offset+=len(tag) |
904 |
s+= "%d\t%s\n" % (offset, length.tblvalue(offset=offset)) |
905 |
offset+=len(length) |
906 |
s+= "%d\t%s\n" % (offset, dp.tblvalue(offset=offset)) |
907 |
offset+=len(dp) |
908 |
for cont in self.value[1:]: |
909 |
tag = cont.value[0] |
910 |
length = cont.value[1] |
911 |
dp = cont.value[2] |
912 |
(tagtype, packetclass) = self.tags.get(tag.value, |
913 |
("Unknown", PacketPart)) |
914 |
|
915 |
s+= "%d\t%s\tTag\t\t%s (%s)\n" % (offset, tag.datatype, |
916 |
tag.value, tagtype) |
917 |
offset+=len(tag) |
918 |
s+= "%d\t%s\n" % (offset, length.tblvalue(offset=offset)) |
919 |
offset+=len(length) |
920 |
s+= "%d\t%s\n" % (offset, dp.tblvalue(offset=offset)) |
921 |
offset+=len(dp) |
922 |
|
923 |
return s |
924 |
|
925 |
def latexvalue(self, offset=0): |
926 |
tag = self.value[0].value[0] |
927 |
length = self.value[0].value[1] |
928 |
dp = self.value[0].value[2] |
929 |
(tagtype, packetclass) = self.tags.get(tag.value, |
930 |
("Unknown", PacketPart)) |
931 |
|
932 |
s = "%s & Tag & & %s (%s)\\\\\n" % (tag.datatype, |
933 |
tag.value, tagtype) |
934 |
offset+=len(tag) |
935 |
s+= "%d & %s \\\\\n" % (offset, length.latexvalue(offset=offset)) |
936 |
offset+=len(length) |
937 |
s+= "%d & %s \\\\\n" % (offset, dp.latexvalue(offset=offset)) |
938 |
offset+=len(dp) |
939 |
for cont in self.value[1:]: |
940 |
tag = cont.value[0] |
941 |
length = cont.value[1] |
942 |
dp = cont.value[2] |
943 |
(tagtype, packetclass) = self.tags.get(tag.value, |
944 |
("Unknown", PacketPart)) |
945 |
|
946 |
s+= "%d & %s & Tag & & %s (%s)\\\\\n" % (offset, tag.datatype, |
947 |
tag.value, tagtype) |
948 |
offset+=len(tag) |
949 |
s+= "%d & %s \\\\ " % (offset, length.latexvalue(offset=offset)) |
950 |
offset+=len(length) |
951 |
s+= "%d & %s \\\\\n" % (offset, dp.latexvalue(offset=offset)) |
952 |
offset+=len(dp) |
953 |
|
954 |
return s |
955 |
|
956 |
|
957 |
|
958 |
class MCSResponseUserdataPacket(PacketPart): |
959 |
|
960 |
classname = "MCSResponseUserdataPacket" |
961 |
|
962 |
def __init__(self, description, **kw): |
963 |
PacketPart.__init__(self, description, **kw) |
964 |
self.datatype = "MCS response userdata" |
965 |
|
966 |
def parse(self, data): |
967 |
userdata_length = BERHeader("Userdata length", |
968 |
self.BER_TAGS['OCTET_STRING'], |
969 |
indent=self.indent) |
970 |
self.value.append(userdata_length) |
971 |
data = userdata_length.parse(data) |
972 |
|
973 |
userdata = data[:userdata_length.value[0].value] |
974 |
|
975 |
t124 = PacketPart("T.124 data", indent=self.indent) |
976 |
t124.parse(userdata[:21]) |
977 |
self.value.append(t124) |
978 |
|
979 |
userdata = userdata[21:] |
980 |
|
981 |
remlength = MSVariableInt("Remaining length "\ |
982 |
"(remaining bytes: %d)" % len(userdata), |
983 |
indent=self.indent) |
984 |
self.value.append(remlength) |
985 |
|
986 |
userdata = remlength.parse(userdata) |
987 |
|
988 |
tagged_data = TaggedData("Tagged data", indent=self.indent) |
989 |
self.value.append(tagged_data) |
990 |
userdata = tagged_data.parse(userdata) |
991 |
|
992 |
if 0 < len(userdata): |
993 |
remaining_data = PacketPart("Remaining MCS response user data", |
994 |
indent=self.indent) |
995 |
self.value.append(remaining_data) |
996 |
remaining_data.parse(userdata) |
997 |
|
998 |
return data[userdata_length.value[0].value:] |
999 |
|
1000 |
class McsInitialUserdataPacket(PacketPart): |
1001 |
|
1002 |
classname = "McsInitialUserdataPacket" |
1003 |
|
1004 |
def __init__(self, description, **kw): |
1005 |
PacketPart.__init__(self, description, **kw) |
1006 |
self.datatype = "MCS initial userdata" |
1007 |
|
1008 |
def parse(self, data): |
1009 |
userdata_length = BERHeader("Userdata length", |
1010 |
self.BER_TAGS['OCTET_STRING'], |
1011 |
indent=self.indent) |
1012 |
self.value.append(userdata_length) |
1013 |
self.value.append(Integer16Part("", knvalue=0x05, indent=self.indent)) |
1014 |
self.value.append(Integer16Part("", knvalue=0x14, indent=self.indent)) |
1015 |
self.value.append(Integer8Part("", knvalue=0x7c, indent=self.indent)) |
1016 |
self.value.append(Integer16Part("", knvalue=0x01, indent=self.indent)) |
1017 |
|
1018 |
for dp in self.value: |
1019 |
data = dp.parse(data) |
1020 |
|
1021 |
vallen = len(self.value) |
1022 |
|
1023 |
remlen = Integer16or8000Part("Remaining length "\ |
1024 |
"(should be %d)" % (len(data)-2), |
1025 |
indent=self.indent) |
1026 |
self.value.append(remlen) |
1027 |
|
1028 |
self.value.append(Integer16Part("", knvalue=0x08, indent=self.indent)) |
1029 |
self.value.append(Integer16Part("", knvalue=0x0f, indent=self.indent)) |
1030 |
self.value.append(Integer8Part("", knvalue=0x00, indent=self.indent)) |
1031 |
self.value.append(Integer16Part("", knvalue=0xc001, |
1032 |
indent=self.indent)) |
1033 |
self.value.append(Integer8Part("", knvalue=0x00, indent=self.indent)) |
1034 |
self.value.append(Integer32lePart("", knvalue="0x61637544 \"Duca\"", |
1035 |
indent=self.indent)) |
1036 |
|
1037 |
for dp in self.value[vallen:]: |
1038 |
data = dp.parse(data) |
1039 |
|
1040 |
remlen = Integer16or8000Part("Remaining length "\ |
1041 |
"(should be %d)" % (len(data)-2), |
1042 |
indent=self.indent) |
1043 |
self.value.append(remlen) |
1044 |
data = remlen.parse(data) |
1045 |
|
1046 |
|
1047 |
clientinfo = UserdataClientinfoPacket("", indent=self.indent+1) |
1048 |
self.value.append(clientinfo) |
1049 |
data = clientinfo.parse(data) |
1050 |
|
1051 |
td = TaggedData("", indent=self.indent+1) |
1052 |
self.value.append(td) |
1053 |
data = td.parse(data) |
1054 |
|
1055 |
if len(data): |
1056 |
remaining_userdata = PacketPart("Remaining user data", |
1057 |
indent=self.indent) |
1058 |
self.value.append(remaining_userdata) |
1059 |
data = remaining_userdata.parse(data) |
1060 |
|
1061 |
return data[remlen.value:] |
1062 |
|
1063 |
|
1064 |
|
1065 |
class MCSConnInitialPacket(PacketPart): |
1066 |
|
1067 |
classname = "MCSConnInitialPacket" |
1068 |
|
1069 |
def __init__(self, description, **kw): |
1070 |
PacketPart.__init__(self, description, **kw) |
1071 |
self.datatype = "MCS Connect Initial" |
1072 |
|
1073 |
def parse(self, data): |
1074 |
conn_initial_header = BERHeader("MCS Conn initial", |
1075 |
self.BER_TAGS['CONN_INITIAL'], |
1076 |
indent=self.indent) |
1077 |
self.value.append(conn_initial_header) |
1078 |
self.value.append(BERValue("Calling Domain", 'OCTET_STRING', |
1079 |
indent=self.indent)) |
1080 |
|
1081 |
self.value.append(BERValue("Called Domain", 'OCTET_STRING', |
1082 |
indent=self.indent)) |
1083 |
self.value.append(BERValue("Upward flag", 'BOOLEAN', |
1084 |
indent=self.indent)) |
1085 |
|
1086 |
self.value.append(DomainParametersPacket("Target", indent=self.indent)) |
1087 |
self.value.append(DomainParametersPacket("Min", indent=self.indent)) |
1088 |
self.value.append(DomainParametersPacket("Max", indent=self.indent)) |
1089 |
self.value.append(McsInitialUserdataPacket("", indent=self.indent)) |
1090 |
|
1091 |
for dp in self.value: |
1092 |
data = dp.parse(data) |
1093 |
|
1094 |
# Code below should basically print nothing, when done deencoding |
1095 |
# the whole packet. |
1096 |
|
1097 |
rempkt = PacketPart("Remaining MCS conn initial data", |
1098 |
indent=self.indent) |
1099 |
self.value.append(rempkt) |
1100 |
remdata = rempkt.parse(data[:conn_initial_header.value[0].value]) |
1101 |
return remdata + data[conn_initial_header.value[0].value:] |
1102 |
|
1103 |
|
1104 |
class MCSConnResponsePacket(PacketPart): |
1105 |
|
1106 |
classname = "MCSConnResponsePacket" |
1107 |
|
1108 |
def __init__(self, description, **kw): |
1109 |
PacketPart.__init__(self, description, **kw) |
1110 |
self.datatype = "MCS Connect Response" |
1111 |
|
1112 |
def parse(self, data): |
1113 |
self.value.append(BERHeader("MCS Conn response", |
1114 |
self.BER_TAGS['CONN_RESPONSE'], |
1115 |
indent=self.indent)) |
1116 |
self.value.append(BERValue("Result", 'TAG_RESULT', |
1117 |
indent=self.indent)) |
1118 |
self.value.append(BERValue("Connection id", 'INTEGER', |
1119 |
indent=self.indent)) |
1120 |
self.value.append(DomainParametersPacket("Target", indent=self.indent)) |
1121 |
self.value.append(MCSResponseUserdataPacket("User data", |
1122 |
indent=self.indent)) |
1123 |
|
1124 |
for dp in self.value: |
1125 |
data = dp.parse(data) |
1126 |
|
1127 |
return data |
1128 |
|
1129 |
|
1130 |
class EDRQPart(PacketPart): |
1131 |
|
1132 |
classname = "EDRQPart" |
1133 |
|
1134 |
def __init__(self, description, **kw): |
1135 |
PacketPart.__init__(self, description, **kw) |
1136 |
self.datatype = "EDRQ data" |
1137 |
|
1138 |
def parse(self, data): |
1139 |
self.value.append(Integer16lePart("SubHeight", indent=self.indent)) |
1140 |
self.value.append(Integer16lePart("SubInterval", indent=self.indent)) |
1141 |
|
1142 |
for dp in self.value: |
1143 |
data = dp.parse(data) |
1144 |
|
1145 |
return data |
1146 |
|
1147 |
class Enumerated(PacketPart): |
1148 |
|
1149 |
classname = "Enumerated" |
1150 |
|
1151 |
def __init__(self, description, dataparser=Integer8Part, **kw): |
1152 |
PacketPart.__init__(self, description, **kw) |
1153 |
self.dataparser = dataparser("") |
1154 |
|
1155 |
|
1156 |
def parse(self, data): |
1157 |
data = self.dataparser.parse(data) |
1158 |
self.value = self.dataparser.value |
1159 |
res = self.results.get(self.value, "Unknown") |
1160 |
self.parser = PacketPart |
1161 |
self.datatype = res |
1162 |
if type(res) == type(()): |
1163 |
self.datatype = res[0] |
1164 |
self.parser = res[1] |
1165 |
|
1166 |
return data |
1167 |
|
1168 |
def strvalue(self): |
1169 |
return self.dataparser.strvalue()+" %s" % self.datatype |
1170 |
|
1171 |
class MCSResultPart(Enumerated): |
1172 |
|
1173 |
classname = "MCSResultPart" |
1174 |
|
1175 |
results = {0:"RT-SUCCESSFUL", |
1176 |
1:"RT-DOMAIN-MERGING", |
1177 |
2:"RT-DOMAIN-NOT-HIEARCHICAL", |
1178 |
3:"RT-NO-SUCH-CHANNEL", |
1179 |
4:"RT-NO-SUCH-DOMAIN", |
1180 |
5:"RT-NO-SUCH-USER", |
1181 |
6:"RT-NOT-ADMITTED", |
1182 |
7:"RT-OTHER-USER-ID", |
1183 |
8:"RT-PARAMETERS-UNACCEPTABLE", |
1184 |
9:"RT-TOKEN-NOT-AVAILABLE", |
1185 |
10:"RT-TOKEN-NOT-POSSESSED", |
1186 |
11:"RT-TOO-MANY-CHANNELS", |
1187 |
12:"RT-TOO-MANY-TOKENS", |
1188 |
13:"RT-TOO-MANY-USERS", |
1189 |
14:"RT-UNSPECIFIED-FAILURE", |
1190 |
15:"RT-USER-REJECTED"} |
1191 |
|
1192 |
|
1193 |
def __init__(self, description, **kw): |
1194 |
Enumerated.__init__(self, description, **kw) |
1195 |
self.datatype = "AUCF data" |
1196 |
|
1197 |
class DataPriorityPart(Enumerated): |
1198 |
|
1199 |
classname = "DataPriorityPart" |
1200 |
|
1201 |
results = {0:"top", |
1202 |
1:"high", |
1203 |
2:"medium", |
1204 |
3:"low"} |
1205 |
|
1206 |
def __init__(self, description, **kw): |
1207 |
Enumerated.__init__(self, description, **kw) |
1208 |
self.datatype = "Data Priority" |
1209 |
|
1210 |
class AUCFPart(PacketPart): |
1211 |
|
1212 |
classname = "AUCFPart" |
1213 |
|
1214 |
def __init__(self, description, **kw): |
1215 |
PacketPart.__init__(self, description, **kw) |
1216 |
self.datatype = "AUCF data" |
1217 |
|
1218 |
def parse(self, data): |
1219 |
self.value.append(MCSResultPart("", indent=self.indent+1)) |
1220 |
self.value.append(Integer16Part("User id", indent=self.indent+1)) |
1221 |
|
1222 |
for dp in self.value: |
1223 |
data = dp.parse(data) |
1224 |
|
1225 |
return data |
1226 |
|
1227 |
class CJRQPart(PacketPart): |
1228 |
|
1229 |
classname = "CJRQPart" |
1230 |
|
1231 |
def __init__(self, description, **kw): |
1232 |
PacketPart.__init__(self, description, **kw) |
1233 |
self.datatype = "CJRQ data" |
1234 |
|
1235 |
def parse(self, data): |
1236 |
self.value.append(Integer16Part("User id", indent=self.indent+1)) |
1237 |
self.channelid = Integer16Part("Channel id", indent=self.indent+1) |
1238 |
self.value.append(self.channelid) |
1239 |
|
1240 |
for dp in self.value: |
1241 |
data = dp.parse(data) |
1242 |
|
1243 |
global currentchannel |
1244 |
currentchannel = self.channelid.value |
1245 |
|
1246 |
return data |
1247 |
|
1248 |
class CJCFPart(PacketPart): |
1249 |
|
1250 |
classname = "CJCFPart" |
1251 |
|
1252 |
def __init__(self, description, **kw): |
1253 |
PacketPart.__init__(self, description, **kw) |
1254 |
self.datatype = "CJCF data" |
1255 |
|
1256 |
def parse(self, data): |
1257 |
self.value.append(MCSResultPart("", indent=self.indent+1)) |
1258 |
self.value.append(Integer16Part("Initiator (user id)", |
1259 |
indent=self.indent+1)) |
1260 |
self.value.append(Integer16Part("Requested", indent=self.indent+1)) |
1261 |
self.channelid = Integer16Part("Channel id", indent=self.indent+1) |
1262 |
self.value.append(self.channelid) |
1263 |
|
1264 |
for dp in self.value: |
1265 |
data = dp.parse(data) |
1266 |
|
1267 |
global currentchannel |
1268 |
currentchannel = self.channelid.value |
1269 |
|
1270 |
return data |
1271 |
|
1272 |
class LicensePart(PacketPart): |
1273 |
|
1274 |
classname = "LicensePart" |
1275 |
|
1276 |
def __init__(self, description, **kw): |
1277 |
PacketPart.__init__(self, description, **kw) |
1278 |
self.datatype = "License data" |
1279 |
|
1280 |
def parse(self, data): |
1281 |
self.value.append(Integer16lePart("Tag", indent=self.indent)) |
1282 |
length = Integer8Part("Length", indent=self.indent) |
1283 |
self.value.append(length) |
1284 |
|
1285 |
for dp in self.value: |
1286 |
data = dp.parse(data) |
1287 |
|
1288 |
remaining_data = PacketPart("Remaining license data", |
1289 |
indent=self.indent+1) |
1290 |
self.value.append(remaining_data) |
1291 |
remaining_data.parse(data[:length.value-3]) |
1292 |
|
1293 |
return data[length.value-3:] |
1294 |
|
1295 |
class GeneralCapability(PacketPart): |
1296 |
|
1297 |
classname = "GeneralCapability" |
1298 |
|
1299 |
def __init__(self, description, **kw): |
1300 |
PacketPart.__init__(self, description, **kw) |
1301 |
self.datatype = "General Capability set" |
1302 |
|
1303 |
def parse(self, data): |
1304 |
self.value.append(Integer16lePart("OS major type", |
1305 |
indent=self.indent+1)) |
1306 |
self.value.append(Integer16lePart("OS minor type", |
1307 |
indent=self.indent+1)) |
1308 |
self.value.append(Integer16Part("Protocol version", |
1309 |
indent=self.indent+1)) |
1310 |
self.value.append(Integer16Part("Pad", |
1311 |
indent=self.indent+1)) |
1312 |
self.value.append(Integer16Part("Compression types", |
1313 |
indent=self.indent+1)) |
1314 |
self.value.append(Integer16Part("Pad", |
1315 |
indent=self.indent+1)) |
1316 |
self.value.append(Integer16Part("Update capability", |
1317 |
indent=self.indent+1)) |
1318 |
self.value.append(Integer16Part("Remote unshare capability", |
1319 |
indent=self.indent+1)) |
1320 |
self.value.append(Integer16Part("Compression level", |
1321 |
indent=self.indent+1)) |
1322 |
self.value.append(Integer16Part("Pad", |
1323 |
indent=self.indent+1)) |
1324 |
|
1325 |
for dp in self.value: |
1326 |
data = dp.parse(data) |
1327 |
|
1328 |
return data |
1329 |
|
1330 |
class OrderCapability(PacketPart): |
1331 |
|
1332 |
classname = "OrderCapability" |
1333 |
|
1334 |
class OrderCaps(PacketPart): |
1335 |
|
1336 |
classname = "OrderCaps" |
1337 |
|
1338 |
def __init__(self, description, **kw): |
1339 |
PacketPart.__init__(self, description, **kw) |
1340 |
self.datatype = "Orders supported" |
1341 |
|
1342 |
def parse(self, data): |
1343 |
self.value.append(Integer8Part("Dest blt", |
1344 |
indent=self.indent+1, |
1345 |
knvalue=1)) |
1346 |
self.value.append(Integer8Part("Pat blt", |
1347 |
indent=self.indent+1, |
1348 |
knvalue=1)) |
1349 |
self.value.append(Integer8Part("Screen blt", |
1350 |
indent=self.indent+1, |
1351 |
knvalue=1)) |
1352 |
self.value.append(Integer8Part("Req for memblt?", |
1353 |
indent=self.indent+1, |
1354 |
knvalue=1)) |
1355 |
self.value.append(Integer8Part("Unknown", |
1356 |
indent=self.indent+1, |
1357 |
knvalue=0)) |
1358 |
self.value.append(Integer8Part("Unknown", |
1359 |
indent=self.indent+1, |
1360 |
knvalue=0)) |
1361 |
self.value.append(Integer8Part("Unknown", |
1362 |
indent=self.indent+1, |
1363 |
knvalue=0)) |
1364 |
self.value.append(Integer8Part("Unknown", |
1365 |
indent=self.indent+1, |
1366 |
knvalue=0)) |
1367 |
self.value.append(Integer8Part("Line", |
1368 |
indent=self.indent+1, |
1369 |
knvalue=1)) |
1370 |
self.value.append(Integer8Part("Line", |
1371 |
indent=self.indent+1, |
1372 |
knvalue=1)) |
1373 |
self.value.append(Integer8Part("Rect", |
1374 |
indent=self.indent+1, |
1375 |
knvalue=1)) |
1376 |
self.value.append(Integer8Part("Unknown", |
1377 |
indent=self.indent+1, |
1378 |
knvalue=0)) |
1379 |
self.value.append(Integer8Part("Memblt", |
1380 |
indent=self.indent+1, |
1381 |
knvalue=1)) |
1382 |
self.value.append(Integer8Part("Triblt", |
1383 |
indent=self.indent+1, |
1384 |
knvalue=1)) |
1385 |
self.value.append(Integer8Part("Triblt", |
1386 |
indent=self.indent+1, |
1387 |
knvalue=1)) |
1388 |
self.value.append(Integer8Part("Unknown", |
1389 |
indent=self.indent+1, |
1390 |
knvalue=0)) |
1391 |
self.value.append(Integer8Part("Unknown", |
1392 |
indent=self.indent+1, |
1393 |
knvalue=0)) |
1394 |
self.value.append(Integer8Part("Unknown", |
1395 |
indent=self.indent+1, |
1396 |
knvalue=0)) |
1397 |
self.value.append(Integer8Part("Unknown", |
1398 |
indent=self.indent+1, |
1399 |
knvalue=0)) |
1400 |
self.value.append(Integer8Part("Unknown", |
1401 |
indent=self.indent+1, |
1402 |
knvalue=0)) |
1403 |
self.value.append(Integer8Part("Unknown", |
1404 |
indent=self.indent+1, |
1405 |
knvalue=0)) |
1406 |
self.value.append(Integer8Part("Unknown", |
1407 |
indent=self.indent+1, |
1408 |
knvalue=0)) |
1409 |
self.value.append(Integer8Part("Polyline", |
1410 |
indent=self.indent+1, |
1411 |
knvalue=1)) |
1412 |
self.value.append(Integer8Part("Text2", |
1413 |
indent=self.indent+1, |
1414 |
knvalue=1)) |
1415 |
self.value.append(PacketPart("Rem. order support data", |
1416 |
indent=self.indent+1, |
1417 |
maxlength=8)) |
1418 |
|
1419 |
for dp in self.value: |
1420 |
data = dp.parse(data) |
1421 |
|
1422 |
return data |
1423 |
|
1424 |
def __init__(self, description, **kw): |
1425 |
PacketPart.__init__(self, description, **kw) |
1426 |
self.datatype = "Order Capability set" |
1427 |
|
1428 |
def parse(self, data): |
1429 |
self.value.append(PacketPart("Terminal desc, pad", |
1430 |
indent=self.indent+1, |
1431 |
maxlength=20)) |
1432 |
self.value.append(Integer16lePart("Cache X granularity", |
1433 |
knvalue=1, |
1434 |
indent=self.indent+1)) |
1435 |
self.value.append(Integer16lePart("Cache Y granularity", |
1436 |
knvalue=20, |
1437 |
indent=self.indent+1)) |
1438 |
self.value.append(Integer16lePart("Pad", |
1439 |
knvalue=0, |
1440 |
indent=self.indent+1)) |
1441 |
self.value.append(Integer16lePart("Max order level", |
1442 |
knvalue=1, |
1443 |
indent=self.indent+1)) |
1444 |
self.value.append(Integer16lePart("Number of fonts", |
1445 |
knvalue=0x147, |
1446 |
indent=self.indent+1)) |
1447 |
self.value.append(Integer16lePart("Capability flags", |
1448 |
knvalue=0x2a, |
1449 |
indent=self.indent+1)) |
1450 |
self.value.append(self.OrderCaps("Orders supported", |
1451 |
indent=self.indent+1, |
1452 |
maxlength=32)) |
1453 |
self.value.append(Integer16lePart("Text capability flags", |
1454 |
knvalue=0x6a1, |
1455 |
indent=self.indent+1)) |
1456 |
self.value.append(PacketPart("Pad", |
1457 |
indent=self.indent+1, |
1458 |
maxlength=6)) |
1459 |
self.value.append(Integer32lePart("Desktop cache size", |
1460 |
knvalue=0x38400, |
1461 |
indent=self.indent+1)) |
1462 |
self.value.append(Integer32lePart("Unknown", |
1463 |
knvalue=0, |
1464 |
indent=self.indent+1)) |
1465 |
self.value.append(Integer32lePart("Unknown", |
1466 |
knvalue=0x4e4, |
1467 |
indent=self.indent+1)) |
1468 |
|
1469 |
for dp in self.value: |
1470 |
data = dp.parse(data) |
1471 |
|
1472 |
return data |
1473 |
|
1474 |
|
1475 |
|
1476 |
class CapsetPart(PacketPart): |
1477 |
|
1478 |
classname = "CapsetPart" |
1479 |
|
1480 |
class CapabilityType(Integer16lePart): |
1481 |
|
1482 |
classname = "CapabilityType" |
1483 |
|
1484 |
types = {1:('GENERAL', GeneralCapability), |
1485 |
2:('BITMAP', PacketPart), |
1486 |
3:('ORDER', OrderCapability), |
1487 |
4:('BMPCACHE', PacketPart), |
1488 |
5:('CONTROL', PacketPart), |
1489 |
7:('ACTIVATE', PacketPart), |
1490 |
8:('POINTER', PacketPart), |
1491 |
9:('SHARE', PacketPart), |
1492 |
10:('COLCACHE', PacketPart), |
1493 |
13:('UNKNOWN', PacketPart)} |
1494 |
|
1495 |
def strvalue(self): |
1496 |
return Integer16lePart.strvalue(self)+" "+self.pkttype |
1497 |
|
1498 |
def parse(self, data): |
1499 |
data = Integer16lePart.parse(self, data) |
1500 |
(self.pkttype, self.parser) = self.types.get(self.value, |
1501 |
("Unknown", |
1502 |
PacketPart)) |
1503 |
return data |
1504 |
|
1505 |
def __init__(self, description, **kw): |
1506 |
PacketPart.__init__(self, description, **kw) |
1507 |
self.datatype = "Capability set" |
1508 |
|
1509 |
def parse(self, data): |
1510 |
pkttype = self.CapabilityType("Capability type", indent=self.indent+1) |
1511 |
data = pkttype.parse(data) |
1512 |
self.value.append(pkttype) |
1513 |
|
1514 |
pktlen = Integer16lePart("Capability length", indent=self.indent+1) |
1515 |
data = pktlen.parse(data) |
1516 |
self.value.append(pktlen) |
1517 |
|
1518 |
datapart = pkttype.parser("", indent=self.indent+1, |
1519 |
maxlength=pktlen.value-4) |
1520 |
data = datapart.parse(data) |
1521 |
self.value.append(datapart) |
1522 |
|
1523 |
return data |
1524 |
|
1525 |
|
1526 |
class DemandActivePart(PacketPart): |
1527 |
|
1528 |
classname = "DemandActivePart" |
1529 |
|
1530 |
def __init__(self, description, **kw): |
1531 |
PacketPart.__init__(self, description, **kw) |
1532 |
self.datatype = "Demand Active data" |
1533 |
|
1534 |
def parse(self, data): |
1535 |
self.value.append(Integer32lePart("Share ID", indent=self.indent+1)) |
1536 |
sourcelen = Integer16lePart("Length of source", |
1537 |
indent=self.indent+1) |
1538 |
self.value.append(sourcelen) |
1539 |
self.value.append(Integer16lePart("Capabilities length", |
1540 |
indent=self.indent+1)) |
1541 |
|
1542 |
for dp in self.value: |
1543 |
data = dp.parse(data) |
1544 |
|
1545 |
valuelen = len(self.value) |
1546 |
|
1547 |
self.value.append(PacketPart("Source", indent=self.indent+1, |
1548 |
maxlength=sourcelen.value)) |
1549 |
|
1550 |
numcapabilities = Integer16lePart("Number of capabilities", |
1551 |
indent=self.indent+1) |
1552 |
self.value.append(numcapabilities) |
1553 |
self.value.append(Integer16lePart("Pad", |
1554 |
indent=self.indent+1)) |
1555 |
self.value.append(Integer16lePart("Pad", |
1556 |
indent=self.indent+1)) |
1557 |
self.value.append(Integer16lePart("Pad", |
1558 |
indent=self.indent+1)) |
1559 |
|
1560 |
self.value.append(Integer16lePart("User ID", indent=self.indent+1)) |
1561 |
|
1562 |
self.value.append(Integer16lePart("Pad", |
1563 |
indent=self.indent+1)) |
1564 |
|
1565 |
for dp in self.value[valuelen:]: |
1566 |
data = dp.parse(data) |
1567 |
|
1568 |
for i in range(numcapabilities.value): |
1569 |
capability = CapsetPart("", indent=self.indent+1) |
1570 |
data = capability.parse(data) |
1571 |
self.value.append(capability) |
1572 |
|
1573 |
remaining_data = PacketPart("Remaining capability data", |
1574 |
indent=self.indent+1) |
1575 |
self.value.append(remaining_data) |
1576 |
|
1577 |
data = remaining_data.parse(data) |
1578 |
|
1579 |
return data |
1580 |
|
1581 |
class ConfirmActivePart(PacketPart): |
1582 |
|
1583 |
classname = "ConfirmActivePart" |
1584 |
|
1585 |
def __init__(self, description, **kw): |
1586 |
PacketPart.__init__(self, description, **kw) |
1587 |
self.datatype = "Confirm Active data" |
1588 |
|
1589 |
def parse(self, data): |
1590 |
self.value.append(Integer32lePart("Share ID", indent=self.indent+1)) |
1591 |
self.value.append(Integer16lePart("User ID", indent=self.indent+1)) |
1592 |
sourcelen = Integer16lePart("Length of source", |
1593 |
indent=self.indent+1) |
1594 |
self.value.append(sourcelen) |
1595 |
self.value.append(Integer16lePart("Capabilities length", |
1596 |
indent=self.indent+1)) |
1597 |
|
1598 |
for dp in self.value: |
1599 |
data = dp.parse(data) |
1600 |
|
1601 |
valuelen = len(self.value) |
1602 |
|
1603 |
self.value.append(PacketPart("Source", indent=self.indent+1, |
1604 |
maxlength=sourcelen.value)) |
1605 |
|
1606 |
numcapabilities = Integer16lePart("Number of capabilities", |
1607 |
indent=self.indent+1) |
1608 |
self.value.append(numcapabilities) |
1609 |
self.value.append(Integer16lePart("Pad", |
1610 |
indent=self.indent+1)) |
1611 |
|
1612 |
for dp in self.value[valuelen:]: |
1613 |
data = dp.parse(data) |
1614 |
|
1615 |
for i in range(numcapabilities.value): |
1616 |
capability = CapsetPart("", indent=self.indent+1) |
1617 |
data = capability.parse(data) |
1618 |
self.value.append(capability) |
1619 |
|
1620 |
remaining_data = PacketPart("Remaining capability data", |
1621 |
indent=self.indent+1) |
1622 |
self.value.append(remaining_data) |
1623 |
|
1624 |
data = remaining_data.parse(data) |
1625 |
|
1626 |
return data |
1627 |
|
1628 |
class DataPDUSynchronize(PacketPart): |
1629 |
|
1630 |
classname = "DataPDUSynchronize" |
1631 |
|
1632 |
def __init__(self, description, **kw): |
1633 |
PacketPart.__init__(self, description, **kw) |
1634 |
self.datatype = "RDP Data PDU Synchronize" |
1635 |
|
1636 |
def parse(self, data): |
1637 |
self.value.append(Integer16lePart("Type", indent=self.indent+1)) |
1638 |
self.value.append(Integer16lePart("Userid(?)", indent=self.indent+1)) |
1639 |
|
1640 |
for dp in self.value: |
1641 |
data = dp.parse(data) |
1642 |
|
1643 |
return data |
1644 |
|
1645 |
class DataPDUControl(PacketPart): |
1646 |
|
1647 |
classname = "DataPDUControl" |
1648 |
|
1649 |
class DataPDUControlType(Enumerated): |
1650 |
|
1651 |
classname = "DataPDUControlType" |
1652 |
|
1653 |
results = {1:'Request control', |
1654 |
2:'Grant control', |
1655 |
3:'Control detach', |
1656 |
4:'Cooperate'} |
1657 |
|
1658 |
def __init__(self, description, **kw): |
1659 |
Enumerated.__init__(self, description, |
1660 |
dataparser=Integer16lePart, **kw) |
1661 |
self.datatype = "RDP Control" |
1662 |
|
1663 |
|
1664 |
def __init__(self, description, **kw): |
1665 |
PacketPart.__init__(self, description, **kw) |
1666 |
self.datatype = "RDP Data PDU Control" |
1667 |
|
1668 |
def parse(self, data): |
1669 |
self.value.append(self.DataPDUControlType("Action", |
1670 |
indent=self.indent+1)) |
1671 |
self.value.append(Integer16Part("Userid(?)", indent=self.indent+1)) |
1672 |
# FIXME - Integer32 (not le) in rdesktop |
1673 |
self.value.append(Integer32lePart("Control id", |
1674 |
indent=self.indent+1)) |
1675 |
|
1676 |
for dp in self.value: |
1677 |
data = dp.parse(data) |
1678 |
|
1679 |
return data |
1680 |
|
1681 |
class DataPDUFont(PacketPart): |
1682 |
|
1683 |
classname = "DataPDUFont" |
1684 |
|
1685 |
def __init__(self, description, **kw): |
1686 |
PacketPart.__init__(self, description, **kw) |
1687 |
self.datatype = "RDP Data PDU Font" |
1688 |
|
1689 |
def parse(self, data): |
1690 |
self.value.append(Integer16Part("Number of fonts", |
1691 |
indent=self.indent+1)) |
1692 |
self.value.append(Integer16lePart("Unknown", |
1693 |
indent=self.indent+1, |
1694 |
knvalue=0x3e)) |
1695 |
self.value.append(Integer16lePart("Unknown (Sequence?)", |
1696 |
indent=self.indent+1)) |
1697 |
self.value.append(Integer16lePart("Entry size", indent=self.indent+1, |
1698 |
knvalue=0x32)) |
1699 |
|
1700 |
for dp in self.value: |
1701 |
data = dp.parse(data) |
1702 |
|
1703 |
return data |
1704 |
|
1705 |
class DataPDUInput(PacketPart): |
1706 |
|
1707 |
classname = "DataPDUInput" |
1708 |
|
1709 |
class InputEvent(PacketPart): |
1710 |
|
1711 |
classname = "InputEvent" |
1712 |
|
1713 |
class MessageType(Enumerated): |
1714 |
|
1715 |
classname = "MessageType" |
1716 |
|
1717 |
results = {0:'Synchronize', |
1718 |
1:'Codepoint', |
1719 |
2:'Virtual key', |
1720 |
4:'Scancode', |
1721 |
0x8001:'Mouse'} |
1722 |
|
1723 |
def __init__(self, description, **kw): |
1724 |
Enumerated.__init__(self, description, |
1725 |
dataparser=Integer16lePart, **kw) |
1726 |
|
1727 |
class ScanCodePart(Integer16lePart): |
1728 |
classname = "ScanCodePart" |
1729 |
|
1730 |
def strvalue(self): |
1731 |
return Integer16lePart.strvalue(self) + " (%s)" % keys[self.value] |
1732 |
|
1733 |
def __init__(self, description, **kw): |
1734 |
PacketPart.__init__(self, description, **kw) |
1735 |
self.datatype = "Input event" |
1736 |
|
1737 |
def parse(self, data): |
1738 |
self.value.append(Time32le("Event timestamp", |
1739 |
indent=self.indent+1)) |
1740 |
mt = self.MessageType("Event type", |
1741 |
indent=self.indent+1) |
1742 |
|
1743 |
self.value.append(mt) |
1744 |
|
1745 |
# Stoppa in parsning av keycode här på nått sätt. *bonk* |
1746 |
|
1747 |
# Fixme: We should have an enumerated here. |
1748 |
self.value.append(Integer16lePart("Device flags", |
1749 |
indent=self.indent+1)) |
1750 |
for dp in self.value: |
1751 |
data = dp.parse(data) |
1752 |
valuelen = len(self.value) |
1753 |
|
1754 |
if 4 == mt.value: |
1755 |
self.value.append(self.ScanCodePart("Key number", |
1756 |
indent=self.indent+1)) |
1757 |
else: |
1758 |
self.value.append(Integer16lePart("Param #1", |
1759 |
indent=self.indent+1)) |
1760 |
self.value.append(Integer16lePart("Param #2", |
1761 |
indent=self.indent+1)) |
1762 |
|
1763 |
for dp in self.value[valuelen:]: |
1764 |
data = dp.parse(data) |
1765 |
|
1766 |
return data |
1767 |
|
1768 |
|
1769 |
def __init__(self, description, **kw): |
1770 |
PacketPart.__init__(self, description, **kw) |
1771 |
self.datatype = "RDP Data PDU Input" |
1772 |
|
1773 |
def parse(self, data): |
1774 |
numevents = Integer16lePart("Number of inputs", indent=self.indent+1) |
1775 |
self.value.append(numevents) |
1776 |
data = numevents.parse(data) |
1777 |
|
1778 |
self.value.append(Integer16Part("Pad", indent=self.indent+1, |
1779 |
knvalue=0)) |
1780 |
for ordernum in range(numevents.value): |
1781 |
self.value.append(self.InputEvent("%d" % (ordernum+1), |
1782 |
indent=self.indent+1)) |
1783 |
|
1784 |
for dp in self.value[1:]: |
1785 |
data = dp.parse(data) |
1786 |
|
1787 |
return data |
1788 |
|
1789 |
|
1790 |
|
1791 |
class RDP_DATA_PDUType(Enumerated): |
1792 |
|
1793 |
classname = "RDP_DATA_PDUType" |
1794 |
|
1795 |
results = {2:'Update', |
1796 |
20:('Control', DataPDUControl), |
1797 |
27:'Pointer', |
1798 |
28:('Input', DataPDUInput), |
1799 |
31:('Synchronize', DataPDUSynchronize), |
1800 |
34:'Bell', |
1801 |
38:'Logon', |
1802 |
39:('Font2', DataPDUFont)} |
1803 |
|
1804 |
|
1805 |
def __init__(self, description, **kw): |
1806 |
Enumerated.__init__(self, description, **kw) |
1807 |
self.datatype = "Data PDUType" |
1808 |
|
1809 |
|
1810 |
class RDP_PDU_DataPart(PacketPart): |
1811 |
|
1812 |
classname = "RDP_PDU_DataPart" |
1813 |
|
1814 |
def __init__(self, description, **kw): |
1815 |
PacketPart.__init__(self, description, **kw) |
1816 |
self.datatype = "RDP data PDU" |
1817 |
|
1818 |
def parse(self, data): |
1819 |
self.value.append(Integer32lePart("Share id", indent=self.indent+1)) |
1820 |
self.value.append(Integer8Part("Pad", indent=self.indent+1, |
1821 |
knvalue=0)) |
1822 |
self.value.append(Integer8Part("Stream id", indent=self.indent+1, |
1823 |
knvalue=1)) |
1824 |
self.value.append(Integer16lePart("Remaining length", |
1825 |
indent=self.indent+1, |
1826 |
knvalue=len(data)-8)) |
1827 |
rdpt = RDP_DATA_PDUType("", indent=self.indent+1) |
1828 |
self.value.append(rdpt) |
1829 |
self.value.append(Integer8Part("Compress type", indent=self.indent+1)) |
1830 |
self.value.append(Integer16Part("Compressed length", |
1831 |
indent=self.indent+1)) |
1832 |
for dp in self.value: |
1833 |
data = dp.parse(data) |
1834 |
|
1835 |
remaining_data = rdpt.parser("", indent=self.indent+1) |
1836 |
self.value.append(remaining_data) |
1837 |
|
1838 |
data = remaining_data.parse(data) |
1839 |
|
1840 |
return data |
1841 |
|
1842 |
class RDP_PDUtype(Integer16lePart): |
1843 |
|
1844 |
classname = "RDP_PDUtype" |
1845 |
|
1846 |
types = {1:('DEMAND_ACTIVE', DemandActivePart), |
1847 |
3:('CONFIRM_ACTIVE', ConfirmActivePart), |
1848 |
6:('DEACTIVATE', PacketPart), |
1849 |
7:('DATA', RDP_PDU_DataPart)} |
1850 |
|
1851 |
def __init__(self, description, **kw): |
1852 |
Integer16lePart.__init__(self, description, **kw) |
1853 |
self.datatype = "RDP pdu type" |
1854 |
|
1855 |
def parse(self, data): |
1856 |
data = Integer16lePart.parse(self, data) |
1857 |
(self.typestr, self.parser) = self.types.get((self.value & 0xf), |
1858 |
("Unknown", PacketPart)) |
1859 |
return data |
1860 |
|
1861 |
def strvalue(self): |
1862 |
return Integer16lePart.strvalue(self)+\ |
1863 |
" & 0xf = %d (%s)" % (self.value & 0xf, self.typestr) |
1864 |
|
1865 |
class SDIN_RDPData(PacketPart): |
1866 |
|
1867 |
classname = "SDIN_RDPData" |
1868 |
|
1869 |
def __init__(self, description, **kw): |
1870 |
PacketPart.__init__(self, description, **kw) |
1871 |
self.datatype = "RDP payload" |
1872 |
|
1873 |
def parse(self, data): |
1874 |
length = Integer16lePart("Length", indent=self.indent+1) |
1875 |
self.value.append(length) |
1876 |
pdutype = RDP_PDUtype("Packet type", |
1877 |
indent=self.indent+1) |
1878 |
self.value.append(pdutype) |
1879 |
self.value.append(Integer16lePart("User id", |
1880 |
indent=self.indent+1)) |
1881 |
|
1882 |
for dp in self.value: |
1883 |
data = dp.parse(data) |
1884 |
|
1885 |
remaining_data = pdutype.parser("", indent=self.indent+1) |
1886 |
self.value.append(remaining_data) |
1887 |
data = remaining_data.parse(data) |
1888 |
|
1889 |
return data |
1890 |
|
1891 |
|
1892 |
class RDPLogonPart(PacketPart): |
1893 |
|
1894 |
classname = "RDPLogonPart" |
1895 |
|
1896 |
class LogonFlags(Integer32lePart): |
1897 |
|
1898 |
classname = "LogonFlags" |
1899 |
|
1900 |
flags = [(0x33, "LOGON_NORMAL"), |
1901 |
(0x8, "LOGON_AUTO"), |
1902 |
(0x100, "BLOB_EXISTS"), |
1903 |
(0x280, "COMPRESS")] |
1904 |
|
1905 |
def __init__(self, description, **kw): |
1906 |
PacketPart.__init__(self, description, **kw) |
1907 |
self.datatype = "RDP Logon Flags" |
1908 |
|
1909 |
def strvalue(self): |
1910 |
ret = Integer32lePart.strvalue(self)+" " |
1911 |
for flag, desc in self.flags: |
1912 |
if self.value & flag: |
1913 |
ret+="%s, " % desc |
1914 |
|
1915 |
return ret |
1916 |
|
1917 |
|
1918 |
|
1919 |
def __init__(self, description, **kw): |
1920 |
PacketPart.__init__(self, description, **kw) |
1921 |
self.datatype = "RDP Logon packet" |
1922 |
|
1923 |
def parse(self, data): |
1924 |
self.value.append(Integer32Part("Unknown", indent=self.indent+1, |
1925 |
knvalue=0)) |
1926 |
logonflags = self.LogonFlags("", indent=self.indent+1) |
1927 |
self.value.append(logonflags) |
1928 |
len_domain = Integer16lePart("Domain length", indent=self.indent+1) |
1929 |
len_user = Integer16lePart("User length", indent=self.indent+1) |
1930 |
self.value+=[len_domain, len_user] |
1931 |
|
1932 |
for dp in self.value: |
1933 |
data = dp.parse(data) |
1934 |
valuelen = len(self.value) |
1935 |
|
1936 |
if logonflags.value & 0x8: |
1937 |
len_password = Integer16lePart("Password length", |
1938 |
indent=self.indent+1) |
1939 |
self.value.append(len_password) |
1940 |
|
1941 |
len_blob = Integer16lePart("BLOB length", |
1942 |
indent=self.indent+1) |
1943 |
len_blob.value = 0 |
1944 |
if logonflags.value & 0x100: |
1945 |
self.value.append(len_blob) |
1946 |
len_program = Integer16lePart("Program length", |
1947 |
indent=self.indent+1) |
1948 |
self.value.append(len_program) |
1949 |
|
1950 |
for dp in self.value[valuelen:]: |
1951 |
data = dp.parse(data) |
1952 |
|
1953 |
valuelen = len(self.value) |
1954 |
|
1955 |
len_directory = Integer16lePart("Directory length", indent=self.indent+1) |
1956 |
len_directory.value = 0 |
1957 |
|
1958 |
# if 0 < len_program.value: |
1959 |
self.value.append(len_directory) |
1960 |
# else: |
1961 |
# self.value.append(Integer16lePart("Instead of directory length", indent=self.indent+1)) |
1962 |
|
1963 |
if 0 < len_domain.value: |
1964 |
self.value.append(UnicodeString("Domain", len_domain.value/2+1, |
1965 |
indent=self.indent+1)) |
1966 |
else: |
1967 |
self.value.append(Integer16lePart("Instead of domain", indent=self.indent+1)) |
1968 |
|
1969 |
if 0 < len_user.value: |
1970 |
self.value.append(UnicodeString("User", len_user.value/2+1, |
1971 |
indent=self.indent+1)) |
1972 |
if logonflags.value & 0x8: |
1973 |
self.value.append(UnicodeString("Password", len_password.value/2+1, |
1974 |
indent=self.indent+1)) |
1975 |
# self.value.append(Integer16lePart("Unknown1", indent=self.indent+1, |
1976 |
# knvalue=0xd806)) |
1977 |
|
1978 |
|
1979 |
if logonflags.value & 0x100: |
1980 |
self.value.append(PacketPart("BLOB", |
1981 |
indent=self.indent+1, |
1982 |
maxlength=len_blob.value)) |
1983 |
self.value.append(Integer16lePart("Unknown2", indent=self.indent+1, |
1984 |
knvalue=0)) |
1985 |
|
1986 |
|
1987 |
for dp in self.value[valuelen:]: |
1988 |
data = dp.parse(data) |
1989 |
|
1990 |
valuelen = len(self.value) |
1991 |
|
1992 |
|
1993 |
if 0 < len_program.value: |
1994 |
self.value.append(UnicodeString("Program", len_program.value/2+1, |
1995 |
indent=self.indent+1)) |
1996 |
else: |
1997 |
self.value.append(Integer16lePart("Instead of Program, #0", indent=self.indent+1)) |
1998 |
if 0 == len_directory.value: |
1999 |
self.value.append(Integer16lePart("Instead of Directory", indent=self.indent+1)) |
2000 |
|
2001 |
if 0 < len_directory.value: |
2002 |
self.value.append(UnicodeString("Directory", |
2003 |
len_directory.value/2+1, |
2004 |
indent=self.indent+1)) |
2005 |
|
2006 |
elif 0 < len_program.value: |
2007 |
self.value.append(Integer16lePart("Instead of directory", |
2008 |
indent=self.indent+1)) |
2009 |
|
2010 |
|
2011 |
self.value.append(Integer16lePart("Unknown", knvalue=2, |
2012 |
indent=self.indent+1)) |
2013 |
|
2014 |
iplen = Integer16lePart("Client ip length", indent=self.indent+1) |
2015 |
self.value.append(iplen) |
2016 |
|
2017 |
for dp in self.value[valuelen:]: |
2018 |
data = dp.parse(data) |
2019 |
valuelen = len(self.value) |
2020 |
|
2021 |
|
2022 |
|
2023 |
self.value.append(UnicodeString("Client ip", iplen.value/2, indent=self.indent+1)) |
2024 |
|
2025 |
for dp in self.value[valuelen:]: |
2026 |
data = dp.parse(data) |
2027 |
valuelen = len(self.value) |
2028 |
|
2029 |
|
2030 |
if 0 < len(data): # This data seems to be here only when running RDP 5.2 (maybe in .1) |
2031 |
|
2032 |
dllstrlen = Integer16lePart("DLL String length", |
2033 |
indent=self.indent+1) |
2034 |
self.value.append(dllstrlen) |
2035 |
data = dllstrlen.parse(data) |
2036 |
valuelen+=1 |
2037 |
|
2038 |
self.value.append(UnicodeString("DLL/executable used", dllstrlen.value/2, indent=self.indent+1)) |
2039 |
|
2040 |
self.value.append(Integer16lePart("Unknown3", knvalue=0xffc4, indent=self.indent+1)) |
2041 |
self.value.append(Integer16lePart("Unknown3½", knvalue=0xffff, |
2042 |
indent=self.indent+1)) |
2043 |
|
2044 |
self.value.append(UnicodeString("Time zone #0", 32, |
2045 |
indent=self.indent+1)) |
2046 |
|
2047 |
self.value.append(PacketPart("Unknown", indent=self.indent+1, |
2048 |
maxlength=20)) |
2049 |
|
2050 |
self.value.append(UnicodeString("Time zone #1", 32, indent=self.indent+1)) |
2051 |
|
2052 |
self.value.append(PacketPart("Remaining RDP Logon data", |
2053 |
indent=self.indent+1)) |
2054 |
|
2055 |
for dp in self.value[valuelen:]: |
2056 |
data = dp.parse(data) |
2057 |
|
2058 |
return data |
2059 |
|
2060 |
class ClipboardData(PacketPart): |
2061 |
|
2062 |
classname = "ClipboardData" |
2063 |
|
2064 |
class FormatDescription(PacketPart): |
2065 |
classname = "FormatDescription" |
2066 |
|
2067 |
def __init__(self, description, **kw): |
2068 |
PacketPart.__init__(self, description, **kw) |
2069 |
self.datatype = "Clipboard format description" |
2070 |
|
2071 |
def parse(self, data): |
2072 |
self.value.append(Integer32lePart("Numeric code", |
2073 |
indent=self.indent+1)) |
2074 |
self.value.append(UnicodeString("Text representation", 16, |
2075 |
indent=self.indent+1)) |
2076 |
|
2077 |
for dp in self.value: |
2078 |
data = dp.parse(data) |
2079 |
|
2080 |
return data |
2081 |
|
2082 |
class ChannelDataFlags(Integer32lePart): |
2083 |
|
2084 |
classname = "ChannelDataFlags" |
2085 |
|
2086 |
flags = [(1, "FLAG_FIRST"), |
2087 |
(2, "FLAG_LAST"), |
2088 |
(0, "FLAG_MIDDLE"),] |
2089 |
|
2090 |
def __init__(self, description, **kw): |
2091 |
PacketPart.__init__(self, description, **kw) |
2092 |
self.datatype = "Channel data flags" |
2093 |
self.owntbl = 0 |
2094 |
|
2095 |
def strvalue(self): |
2096 |
ret = Integer32lePart.strvalue(self)+" " |
2097 |
for flag, desc in self.flags: |
2098 |
if self.value & flag: |
2099 |
ret+="%s, " % desc |
2100 |
|
2101 |
return ret |
2102 |
|
2103 |
def __init__(self, description, **kw): |
2104 |
PacketPart.__init__(self, description, **kw) |
2105 |
self.datatype = "Clipboard data" |
2106 |
|
2107 |
def parse(self, data): |
2108 |
CHANNEL_FLAG_FIRST = 1 |
2109 |
CHANNEL_FLAG_LAST = 2 |
2110 |
cdlength = Integer32lePart("Clpbrd data length", |
2111 |
indent=self.indent+1) |
2112 |
flags = self.ChannelDataFlags("Flags", |
2113 |
indent=self.indent+1) |
2114 |
|
2115 |
self.value = [cdlength, flags] |
2116 |
|
2117 |
for dp in self.value: |
2118 |
data = dp.parse(data) |
2119 |
|
2120 |
valuelen = len(self.value) |
2121 |
|
2122 |
if flags.value == 2: # Last packet: |
2123 |
self.value.append(PacketPart("Clipboard data, last packet of several", indent=self.indent+1)) |
2124 |
elif flags.value & 0x0f == 0x3: # Single write op. |
2125 |
ptype0 = Integer16lePart("Ptype0", indent=self.indent+1) |
2126 |
ptype1 = Integer16lePart("Ptype1", indent=self.indent+1) |
2127 |
self.value.append(ptype0) |
2128 |
self.value.append(ptype1) |
2129 |
|
2130 |
for dp in self.value[valuelen:]: |
2131 |
data = dp.parse(data) |
2132 |
|
2133 |
valuelen = len(self.value) |
2134 |
|
2135 |
if 2 == ptype0.value: # Format announce |
2136 |
remlen = Integer32lePart("Remaining length", indent=self.indent+1) |
2137 |
self.value.append(remlen) |
2138 |
valuelen+=1 |
2139 |
data = remlen.parse(data) |
2140 |
|
2141 |
for i in range(remlen.value/36): |
2142 |
self.value.append(self.FormatDescription("#%d" % i, |
2143 |
indent=self.indent+1)) |
2144 |
self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1)) |
2145 |
|
2146 |
elif 1 == ptype0.value or 3 == ptype0.value: # First pkt from server / answer to format announce |
2147 |
remlen = Integer32lePart("Remaining length", indent=self.indent+1) |
2148 |
self.value.append(remlen) |
2149 |
valuelen+=1 |
2150 |
data = remlen.parse(data) |
2151 |
|
2152 |
self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1)) |
2153 |
|
2154 |
elif 4 == ptype0.value: # Request data |
2155 |
remlen = Integer32lePart("Remaining length", indent=self.indent+1) |
2156 |
self.value.append(remlen) |
2157 |
valuelen+=1 |
2158 |
data = remlen.parse(data) |
2159 |
|
2160 |
self.value.append(Integer32lePart("Requested format code", indent=self.indent+1)) |
2161 |
self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1)) |
2162 |
|
2163 |
elif 5 == ptype0.value: # Send data |
2164 |
remlen = Integer32lePart("Remaining length", indent=self.indent+1) |
2165 |
self.value.append(remlen) |
2166 |
valuelen+=1 |
2167 |
data = remlen.parse(data) |
2168 |
|
2169 |
if remlen.value > 1600: |
2170 |
datalen = 1592 |
2171 |
else: |
2172 |
datalen = remlen.value |
2173 |
|
2174 |
self.value.append(PacketPart("Clipboard data", indent=self.indent+1, |
2175 |
maxlength=datalen)) |
2176 |
if remlen.value < 1600: |
2177 |
self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1)) |
2178 |
|
2179 |
|
2180 |
elif (not (flags.value & CHANNEL_FLAG_FIRST) and not (flags.value & CHANNEL_FLAG_LAST)) or (flags.value & CHANNEL_FLAG_LAST): |
2181 |
self.value.append(PacketPart("Clipboard data", indent=self.indent+1)) |
2182 |
|
2183 |
for dp in self.value[valuelen:]: |
2184 |
data = dp.parse(data) |
2185 |
|
2186 |
return data |
2187 |
|
2188 |
|
2189 |
class SDINPart(PacketPart): |
2190 |
|
2191 |
classname = "SDINPart" |
2192 |
|
2193 |
def __init__(self, description, **kw): |
2194 |
PacketPart.__init__(self, description, **kw) |
2195 |
self.datatype = "SDIN data" |
2196 |
|
2197 |
def parse(self, data): |
2198 |
self.value.append(Integer16Part("Initiator (user id)", |
2199 |
indent=self.indent+1)) |
2200 |
self.channelid = Integer16Part("Channel id", indent=self.indent+1) |
2201 |
self.value.append(self.channelid) |
2202 |
self.value.append(Integer8Part("Flags", indent=self.indent+1)) |
2203 |
remaining_length = MSVariableInt("Data length", indent=self.indent+1) |
2204 |
self.value.append(remaining_length) |
2205 |
flags = Integer32lePart("Flags(?)", indent=self.indent+1) |
2206 |
self.value.append(flags) |
2207 |
|
2208 |
for dp in self.value: |
2209 |
data = dp.parse(data) |
2210 |
|
2211 |
global currentchannel |
2212 |
currentchannel = self.channelid.value |
2213 |
|
2214 |
valuelen = len(self.value) |
2215 |
|
2216 |
if flags.value & 0x0008: # Encrypted == have signature |
2217 |
self.value.append(CryptoSignature("Crypto signature", |
2218 |
indent=self.indent+1, maxlength=8)) |
2219 |
|
2220 |
if flags.value & 0x0080: # License packet. |
2221 |
self.value.append(LicensePart("", indent=self.indent+1)) |
2222 |
elif 1003 < self.channelid.value: |
2223 |
self.value.append(ClipboardData("", indent=self.indent+1)) |
2224 |
else: |
2225 |
self.value.append(SDIN_RDPData("", indent=self.indent+1)) |
2226 |
|
2227 |
try: |
2228 |
for dp in self.value[valuelen:]: |
2229 |
data = dp.parse(data) |
2230 |
except ValueError: |
2231 |
if flags.value & 0x260000: |
2232 |
mysterious = PacketPart("Mysterious data", |
2233 |
indent=self.indent+1) |
2234 |
self.value.append(mysterious) |
2235 |
data = mysterious.parse(data) |
2236 |
|
2237 |
if 0 < len(data): |
2238 |
rem_data = PacketPart("Remaining SDIN data", |
2239 |
indent=self.indent+1) |
2240 |
data = rem_data.parse(data) |
2241 |
self.value.append(rem_data) |
2242 |
|
2243 |
|
2244 |
return data |
2245 |
|
2246 |
class SDRQPart(PacketPart): |
2247 |
|
2248 |
classname = "SDRQPart" |
2249 |
|
2250 |
def __init__(self, description, **kw): |
2251 |
PacketPart.__init__(self, description, **kw) |
2252 |
self.datatype = "SDRQ data" |
2253 |
|
2254 |
def parse(self, data): |
2255 |
self.value.append(Integer16Part("Initiator (user id)", |
2256 |
indent=self.indent+1)) |
2257 |
self.channelid = Integer16Part("Channel id", indent=self.indent+1) |
2258 |
self.value.append(self.channelid) |
2259 |
self.value.append(Integer8Part("Flags", indent=self.indent+1)) |
2260 |
remaining_length = MSVariableInt("Data length", indent=self.indent+1) |
2261 |
self.value.append(remaining_length) |
2262 |
flags = Integer32lePart("Flags(?)", indent=self.indent+1) |
2263 |
self.value.append(flags) |
2264 |
|
2265 |
for dp in self.value: |
2266 |
data = dp.parse(data) |
2267 |
|
2268 |
global currentchannel |
2269 |
currentchannel = self.channelid.value |
2270 |
|
2271 |
valuelen = len(self.value) |
2272 |
|
2273 |
if flags.value & 0x0008: |
2274 |
cryptsig = CryptoSignature("Crypto signature", indent=self.indent+1) |
2275 |
cryptsig.parse(data[:8]) |
2276 |
data = data[8:] |
2277 |
self.value.append(cryptsig) |
2278 |
|
2279 |
valuelen = len(self.value) |
2280 |
|
2281 |
if flags.value & 0x0040: # RDP Logon info |
2282 |
self.value.append(RDPLogonPart("", indent=self.indent+1)) |
2283 |
|
2284 |
elif flags.value & 0x0080: # License neg. |
2285 |
self.value.append(LicensePart("", indent=self.indent+1)) |
2286 |
elif 1003 < self.channelid.value: |
2287 |
self.value.append(ClipboardData("", indent=self.indent+1)) |
2288 |
else: |
2289 |
self.value.append(SDIN_RDPData("", indent=self.indent+1)) |
2290 |
|
2291 |
elif flags.value & 0x0001: # Client random |
2292 |
saltlen = Integer32lePart("Client salt len", |
2293 |
indent=self.indent+1) |
2294 |
self.value.append(saltlen) |
2295 |
for dp in self.value[valuelen:]: |
2296 |
data = dp.parse(data) |
2297 |
valuelen = len(self.value) |
2298 |
|
2299 |
self.value.append(PacketPart("Client salt", indent=self.indent+1, |
2300 |
maxlength=saltlen.value)) |
2301 |
|
2302 |
else: |
2303 |
|
2304 |
self.value.append(PacketPart("Remaining SDRQ data", |
2305 |
indent=self.indent+1)) |
2306 |
|
2307 |
for dp in self.value[valuelen:]: |
2308 |
data = dp.parse(data) |
2309 |
|
2310 |
return data |
2311 |
|
2312 |
|
2313 |
class MCSPacket(PacketPart): |
2314 |
|
2315 |
classname = "MCSPacket" |
2316 |
|
2317 |
class MCStype8(Integer8Part): |
2318 |
|
2319 |
classname = "MCStype8" |
2320 |
|
2321 |
types = {1:('EDRQ', EDRQPart), |
2322 |
8:('DPUM', PacketPart), |
2323 |
10:('AURQ', PacketPart), |
2324 |
11:('AUCF', AUCFPart), |
2325 |
14:('CJRQ', CJRQPart), |
2326 |
15:('CJCF', CJCFPart), |
2327 |
25:('SDRQ', SDRQPart), |
2328 |
26:('SDIN', SDINPart)} |
2329 |
def strvalue(self): |
2330 |
return "0x%.2x (%d) %s" % (self.value, self.value, |
2331 |
self.typestr) |
2332 |
|
2333 |
def parse(self, data): |
2334 |
data = Integer8Part.parse(self, data) |
2335 |
self.value = self.value >> 2 |
2336 |
(self.typestr, self.parser) = self.types.get(self.value, |
2337 |
("Unknown", |
2338 |
PacketPart)) |
2339 |
return data |
2340 |
|
2341 |
class MCStype16(Integer16Part): |
2342 |
|
2343 |
classname = "MCStype16" |
2344 |
|
2345 |
types = {0x7f65:'Connect Initial', |
2346 |
0x7f66:'Connect Response'} |
2347 |
def strvalue(self): |
2348 |
return "0x%.4x (%d) %s" % (self.value, self.value, |
2349 |
self.types.get(self.value, "Unknown")) |
2350 |
|
2351 |
|
2352 |
def __init__(self, description, **kw): |
2353 |
PacketPart.__init__(self, description, **kw) |
2354 |
self.datatype = "MCS packet" |
2355 |
|
2356 |
def parse(self, data): |
2357 |
origdata = data |
2358 |
mcstype = self.MCStype8("MCS type", indent=self.indent+1) |
2359 |
ndata = mcstype.parse(data) |
2360 |
if 0x1f == mcstype.value: |
2361 |
mcstype = self.MCStype16("MCS type", indent=self.indent+1) |
2362 |
data = mcstype.parse(data) |
2363 |
else: |
2364 |
data = ndata |
2365 |
|
2366 |
if 0x7f65 == mcstype.value: |
2367 |
rempkt = MCSConnInitialPacket("", |
2368 |
indent=self.indent+1) |
2369 |
elif 0x7f66 == mcstype.value: |
2370 |
rempkt = MCSConnResponsePacket("", |
2371 |
indent=self.indent+1) |
2372 |
else: |
2373 |
self.value.append(mcstype) |
2374 |
rempkt = mcstype.parser("", indent=self.indent+1) |
2375 |
self.value.append(rempkt) |
2376 |
return rempkt.parse(data) |
2377 |
|
2378 |
|
2379 |
self.value.append(rempkt) |
2380 |
|
2381 |
# Special case - we print the type twice. Probably not good.. |
2382 |
data = rempkt.parse(origdata) |
2383 |
|
2384 |
return data |
2385 |
|
2386 |
|
2387 |
class ISOPacket(PacketPart): |
2388 |
|
2389 |
classname = "TPDU" |
2390 |
|
2391 |
class ISOPacketType(Integer8Part): |
2392 |
|
2393 |
classname = "TPDU" |
2394 |
|
2395 |
types = {0xe0:'Connection request', |
2396 |
0xd0:'Connection confirm', |
2397 |
0x80:'Disconnect request', |
2398 |
0xf0:'Data', |
2399 |
0x70:'Error'} |
2400 |
|
2401 |
def strvalue(self): |
2402 |
return "0x%.2x (%d) %s" % (self.value, self.value, |
2403 |
self.types.get(self.value, "Unknown")) |
2404 |
def __init__(self, description, **kw): |
2405 |
PacketPart.__init__(self, description, **kw) |
2406 |
self.datatype = "TPDU" |
2407 |
|
2408 |
def parse(self, data): |
2409 |
headerlen = Integer8Part("TPDU hdr length", indent=self.indent+1) |
2410 |
self.value.append(headerlen) |
2411 |
|
2412 |
isotype = self.ISOPacketType("TPDU packet type", indent=self.indent+1) |
2413 |
self.value.append(isotype) |
2414 |
|
2415 |
data = headerlen.parse(data) |
2416 |
data = isotype.parse(data) |
2417 |
|
2418 |
if 2 == headerlen.value: |
2419 |
eot = Integer8Part("TPDU eot", knvalue = 0x80, indent=self.indent+1) |
2420 |
self.value.append(eot) |
2421 |
data = eot.parse(data) |
2422 |
mcs = MCSPacket("", indent=self.indent+1) |
2423 |
self.value.append(mcs) |
2424 |
data = mcs.parse(data) |
2425 |
|
2426 |
else: |
2427 |
dst_ref = Integer16Part("Dst ref", indent=self.indent+1) |
2428 |
self.value.append(dst_ref) |
2429 |
|
2430 |
src_ref = Integer16Part("Src ref", indent=self.indent+1) |
2431 |
self.value.append(src_ref) |
2432 |
|
2433 |
cls = Integer8Part("Class", indent=self.indent+1) |
2434 |
self.value.append(cls) |
2435 |
|
2436 |
data = dst_ref.parse(data) |
2437 |
data = src_ref.parse(data) |
2438 |
data = cls.parse(data) |
2439 |
|
2440 |
return data |
2441 |
|
2442 |
|
2443 |
class TPKT(PacketPart): |
2444 |
|
2445 |
classname = "TPKT" |
2446 |
|
2447 |
def __init__(self, description, **kw): |
2448 |
PacketPart.__init__(self, description, **kw) |
2449 |
self.datatype = "TPKT" |
2450 |
|
2451 |
def parse(self, data): |
2452 |
|
2453 |
self.value.append(Integer8Part("TPKT version", indent=self.indent+1, |
2454 |
knvalue = 3)) |
2455 |
self.value.append(Integer8Part("TPKT reserved", indent=self.indent+1, |
2456 |
knvalue = 0)) |
2457 |
self.value.append(Integer16Part("TPKT length", indent=self.indent+1)) |
2458 |
self.value.append(ISOPacket("", indent=self.indent+1)) |
2459 |
|
2460 |
for dp in self.value: |
2461 |
data = dp.parse(data) |
2462 |
|
2463 |
if (0 < len(data)): |
2464 |
mstshash = Latin1String("mstshash", len(data)-2, nonullchar=1, |
2465 |
indent=self.indent+1) |
2466 |
self.value.append(mstshash) |
2467 |
data = mstshash.parse(data) |
2468 |
|
2469 |
if (0 < len(data)): |
2470 |
remaining = Integer16lePart("Unknown", indent=self.indent+1) |
2471 |
data = remaining.parse(data) |
2472 |
self.value.append(remaining) |
2473 |
|
2474 |
|
2475 |
|
2476 |
|
2477 |
|
2478 |
return data |
2479 |
|
2480 |
|
2481 |
class OrdersPart(PacketPart): |
2482 |
|
2483 |
classname = "OrdersPart" |
2484 |
|
2485 |
def __init__(self, description, **kw): |
2486 |
PacketPart.__init__(self, description, **kw) |
2487 |
self.datatype = "Orders" |
2488 |
|
2489 |
def parse(self, data): |
2490 |
if None != self.maxlength: |
2491 |
returndata = data[self.maxlength:] |
2492 |
data = data[:self.maxlength] |
2493 |
|
2494 |
self.value.append(Integer16lePart("Order count", |
2495 |
indent=self.indent+1)) |
2496 |
self.value.append(PacketPart("Order data", |
2497 |
indent=self.indent+1)) |
2498 |
|
2499 |
for dp in self.value: |
2500 |
data = dp.parse(data) |
2501 |
|
2502 |
return returndata |
2503 |
|
2504 |
|
2505 |
|
2506 |
class BitmapUpdatePart(PacketPart): |
2507 |
|
2508 |
classname = "BitmapUpdatePart" |
2509 |
|
2510 |
class UpdateSubPart(PacketPart): |
2511 |
|
2512 |
classname = "UpdateSubPart" |
2513 |
|
2514 |
def __init__(self, description, **kw): |
2515 |
PacketPart.__init__(self, description, **kw) |
2516 |
self.datatype = "Bitmap update subpart" |
2517 |
|
2518 |
def parse(self, data): |
2519 |
pad = Integer16lePart("Pad?", indent=self.indent+1) |
2520 |
left = Integer16lePart("Left", indent=self.indent+1) |
2521 |
top = Integer16lePart("Top", indent=self.indent+1) |
2522 |
right = Integer16lePart("Right", indent=self.indent+1) |
2523 |
bottom = Integer16lePart("Bottom", indent=self.indent+1) |
2524 |
width = Integer16lePart("Width", indent=self.indent+1) |
2525 |
height = Integer16lePart("Height", indent=self.indent+1) |
2526 |
bpp = Integer16lePart("bpp", indent=self.indent+1) |
2527 |
compress = Integer16lePart("Compress", indent=self.indent+1) |
2528 |
bufsize = Integer16lePart("Bufsize", indent=self.indent+1) |
2529 |
|
2530 |
self.value = [pad, left, top, right, bottom, width, |
2531 |
height, bpp, compress, bufsize] |
2532 |
|
2533 |
for dp in self.value: |
2534 |
data = dp.parse(data) |
2535 |
|
2536 |
bmpdata = None |
2537 |
Bpp = (bpp.value+7) / 8 |
2538 |
|
2539 |
if not compress.value: |
2540 |
bmpdata = PacketPart("BMP data (not compressed)", indent=self.indent+1, |
2541 |
maxlength=width.value*height.value*Bpp) |
2542 |
data = bmpdata.parse(data) |
2543 |
self.value.append(bmpdata) |
2544 |
return data |
2545 |
|
2546 |
valuelen = len(self.value) |
2547 |
|
2548 |
if compress.value & 0x400: |
2549 |
size = bufsize |
2550 |
else: |
2551 |
self.value.append(Integer16Part("Pad", indent=self.indent+1)) |
2552 |
size = Integer16lePart("Size", indent=self.indent+1) |
2553 |
self.value.append(size) |
2554 |
self.value.append(Integer16lePart("Line size", indent=self.indent+1)) |
2555 |
self.value.append(Integer16lePart("Final size", indent=self.indent+1)) |
2556 |
for dp in self.value[valuelen:]: |
2557 |
data = dp.parse(data) |
2558 |
|
2559 |
bmpdata = PacketPart("BMP data (compressed)", indent=self.indent+1, |
2560 |
maxlength=size.value) |
2561 |
data = bmpdata.parse(data) |
2562 |
self.value.append(bmpdata) |
2563 |
return data |
2564 |
|
2565 |
def __init__(self, description, **kw): |
2566 |
PacketPart.__init__(self, description, **kw) |
2567 |
self.datatype = "Bitmap update" |
2568 |
|
2569 |
def parse(self, data): |
2570 |
if None != self.maxlength: |
2571 |
returndata = data[self.maxlength:] |
2572 |
data = data[:self.maxlength] |
2573 |
|
2574 |
num_updates = Integer16lePart("# of updates", indent=self.indent+1) |
2575 |
data = num_updates.parse(data) |
2576 |
self.value.append(num_updates) |
2577 |
|
2578 |
for i in range(num_updates.value): |
2579 |
self.value.append(self.UpdateSubPart("%d" % i, indent=self.indent+1)) |
2580 |
|
2581 |
for dp in self.value[1:]: |
2582 |
data = dp.parse(data) |
2583 |
|
2584 |
if 0 < len(data): |
2585 |
remaining_data = PacketPart("Remaining Bitmap update data", indent=self.indent+1) |
2586 |
remaining_data.parse(data) |
2587 |
self.value.append(remaining_data) |
2588 |
|
2589 |
return returndata |
2590 |
|
2591 |
class RDP5Packet(PacketPart): |
2592 |
|
2593 |
classname = "RDP5Packet" |
2594 |
|
2595 |
class RDP5StartByte(Integer8Part): |
2596 |
|
2597 |
classname = "RDP5StartByte" |
2598 |
|
2599 |
def strvalue(self): |
2600 |
ret = Integer8Part.strvalue(self) |
2601 |
if self.value & 0x80: |
2602 |
ret+=", encrypted" |
2603 |
ret+=", %d inputs" % ((self.value & 124) >> 2) |
2604 |
return ret |
2605 |
|
2606 |
class RDP5PacketType(Enumerated): |
2607 |
|
2608 |
classname = "RDP5PacketType" |
2609 |
|
2610 |
def __init__(self, description, **kw): |
2611 |
Enumerated.__init__(self, description, **kw) |
2612 |
self.datatype = "RDP5 packetpart" |
2613 |
|
2614 |
results = {0x00:('Orders', OrdersPart), |
2615 |
0x01:('Bitmap update', BitmapUpdatePart), |
2616 |
0x02:'Palette', |
2617 |
0x03:'Palette with offset 3(?)', |
2618 |
0x05:'NullSystemPointer(?)', |
2619 |
0x06:'DefaultSystemPointer(?)', |
2620 |
0x07:'MonoPointer(?)', |
2621 |
0x08:'Position(?)', |
2622 |
0x09:'ColourPointer(?)', |
2623 |
0x0a:'CachedPointer(?)', |
2624 |
0x0b:'Mouse pointer (b/w)'} |
2625 |
|
2626 |
def __init__(self, description, **kw): |
2627 |
PacketPart.__init__(self, description, **kw) |
2628 |
self.datatype = "RDP5 packet" |
2629 |
|
2630 |
def encrypted(self): |
2631 |
return self.startbyte.value & 0x80 |
2632 |
|
2633 |
def parse(self, data): |
2634 |
self.startbyte = self.RDP5StartByte("RDP5 start byte", |
2635 |
indent=self.indent+1) |
2636 |
self.value.append(self.startbyte) |
2637 |
|
2638 |
remaining_length = MSVariableInt("Packet length", |
2639 |
indent=self.indent+1, |
2640 |
knvalue=len(data)) |
2641 |
self.value.append(remaining_length) |
2642 |
|
2643 |
valuelen = len(self.value) |
2644 |
|
2645 |
for dp in self.value: |
2646 |
data = dp.parse(data) |
2647 |
|
2648 |
if self.encrypted(): |
2649 |
cryptsig = PacketPart("Cryptsig", indent=self.indent+1) |
2650 |
self.value.append(cryptsig) |
2651 |
cryptsig.parse(data[:8]) |
2652 |
data = data[8:] |
2653 |
valuelen+=1 |
2654 |
|
2655 |
while 0 < len(data): |
2656 |
pt = self.RDP5PacketType("", |
2657 |
indent=self.indent+2) |
2658 |
self.value.append(pt) |
2659 |
data = pt.parse(data) |
2660 |
partlen = Integer16lePart("Partlen(?)", |
2661 |
indent=self.indent+2) |
2662 |
self.value.append(partlen) |
2663 |
data = partlen.parse(data) |
2664 |
|
2665 |
partdata = pt.parser("Part data", indent=self.indent+3, |
2666 |
maxlength=partlen.value) |
2667 |
data = partdata.parse(data) |
2668 |
self.value.append(partdata) |
2669 |
|
2670 |
remaining_data = PacketPart("Remaining data", |
2671 |
indent=self.indent+1) |
2672 |
self.value.append(remaining_data) |
2673 |
return remaining_data.parse(data) |
2674 |
|
2675 |
class LaTeXindex: |
2676 |
def __init__(self): |
2677 |
self.figs = [] |
2678 |
|
2679 |
def append(self, filename, description): |
2680 |
self.figs.append((filename, description)) |
2681 |
|
2682 |
def __str__(self): |
2683 |
ret = """ |
2684 |
\\documentclass{report} |
2685 |
\\usepackage[english]{babel} |
2686 |
\\usepackage[latin1]{inputenc} |
2687 |
\\usepackage{graphicx} |
2688 |
\\begin{document} |
2689 |
|
2690 |
""" |
2691 |
for (filename, description) in self.figs: |
2692 |
ret+= """ |
2693 |
\\begin{figure}[h] |
2694 |
\\includegraphics{%s.eps} |
2695 |
\\caption{%s} |
2696 |
\\label{fig:%s} |
2697 |
\\end{figure} |
2698 |
|
2699 |
""" % (filename, description, filename) |
2700 |
|
2701 |
ret+= """ |
2702 |
\\end{document} |
2703 |
|
2704 |
|
2705 |
""" |
2706 |
return ret |
2707 |
|
2708 |
|
2709 |
|
2710 |
|
2711 |
|
2712 |
clsrefs = {} |
2713 |
|
2714 |
|
2715 |
def create_tbl(ofile, p, origin, totpacketno, packetno, |
2716 |
location, classnames, infilename): |
2717 |
if "Server" == origin: |
2718 |
origin = "S" |
2719 |
else: |
2720 |
origin = "C" |
2721 |
|
2722 |
class PlaceHolder(PacketPart): |
2723 |
def strvalue(self): |
2724 |
return self.value |
2725 |
|
2726 |
def rec(part, res, packetno): |
2727 |
if type([]) == type(part.value): |
2728 |
newvalue = [] |
2729 |
partno = 0 |
2730 |
for subpart in part.value: |
2731 |
if isinstance(subpart, PacketPart) and subpart.owntbl: |
2732 |
subpart.packetno = "%s%d" % (packetno, partno) |
2733 |
res.append(subpart) |
2734 |
rec(subpart, res, "%s%d-" % (packetno, partno)) |
2735 |
|
2736 |
placeholder = PlaceHolder(subpart.description) |
2737 |
placeholder.datatype = subpart.datatype |
2738 |
placeholder.value = "See %s%s%d" % (origin, packetno, partno) |
2739 |
newvalue.append(placeholder) |
2740 |
|
2741 |
partno+=1 |
2742 |
else: |
2743 |
newvalue.append(subpart) |
2744 |
part.value = newvalue |
2745 |
|
2746 |
|
2747 |
if 0 == totpacketno: |
2748 |
return |
2749 |
|
2750 |
res = [p] |
2751 |
p.packetno = packetno |
2752 |
rec(p, res, "%d-" % packetno) |
2753 |
|
2754 |
outfile = None |
2755 |
|
2756 |
for ppart in res: |
2757 |
if location: |
2758 |
if outfile: |
2759 |
outfile.close() |
2760 |
if classnames: |
2761 |
num = 0 |
2762 |
if clsrefs.has_key(ppart.classname): |
2763 |
num = clsrefs[ppart.classname] |
2764 |
clsrefs[ppart.classname]+=1 |
2765 |
else: |
2766 |
clsrefs[ppart.classname]=1 |
2767 |
path = os.path.join(location, "%s-%d-%s%d-%s-%d.tbl" % (infilename.replace(".", "-"), totpacketno, origin, packetno, ppart.classname, num)) |
2768 |
else: |
2769 |
path = os.path.join(location, "%s%s.tbl" % (origin, ppart.packetno)) |
2770 |
outfile = open(path, 'w') |
2771 |
else: |
2772 |
outfile = ofile |
2773 |
print >> outfile, """ |
2774 |
.TS |
2775 |
box; |
2776 |
lB| cB s s s s |
2777 |
r l l l l l |
2778 |
r l l l l l. |
2779 |
%s%s (%s)\t%s %s\t |
2780 |
_ |
2781 |
Offset\tDatatype\tDescription\tExpected value\tValue\t |
2782 |
_""" % (origin, ppart.packetno, ppart.classname, ppart.datatype, ppart.description) |
2783 |
|
2784 |
s = "" |
2785 |
offset = 0 |
2786 |
if type([]) == type(ppart.value): |
2787 |
for subpart in ppart.value: |
2788 |
if type("") == type(subpart): |
2789 |
print >> outfile, "(str)\t\t\t%s\t" % (subpart) |
2790 |
else: |
2791 |
print >> outfile, "%d\t%s" % (offset, |
2792 |
subpart.tblvalue(offset=offset)) |
2793 |
offset+=len(subpart) |
2794 |
|
2795 |
else: |
2796 |
s = "off\t%s\t%s\t" % (ppart.datatype, |
2797 |
ppart.description) |
2798 |
if None != ppart.knvalue: |
2799 |
s+=str(ppart.knvalue) |
2800 |
s+="\t%s\t" % ppart.value |
2801 |
print >> outfile, s |
2802 |
print >> outfile, ".TE\n" |
2803 |
|
2804 |
|
2805 |
def create_latex(ofile, p, origin, totpacketno, packetno, |
2806 |
location, classnames, infilename): |
2807 |
if "Server" == origin: |
2808 |
origin = "S" |
2809 |
else: |
2810 |
origin = "C" |
2811 |
|
2812 |
class PlaceHolder(PacketPart): |
2813 |
def strvalue(self): |
2814 |
return self.value |
2815 |
|
2816 |
def rec(part, res, packetno): |
2817 |
if type([]) == type(part.value): |
2818 |
newvalue = [] |
2819 |
partno = 0 |
2820 |
for subpart in part.value: |
2821 |
if isinstance(subpart, PacketPart) and subpart.owntbl: |
2822 |
subpart.packetno = "%s%d" % (packetno, partno) |
2823 |
res.append(subpart) |
2824 |
rec(subpart, res, "%s%d-" % (packetno, partno)) |
2825 |
|
2826 |
placeholder = PlaceHolder(subpart.description) |
2827 |
placeholder.datatype = subpart.datatype |
2828 |
placeholder.value = "\pktref{%s%s%d}" % (origin, |
2829 |
packetno, |
2830 |
partno) |
2831 |
newvalue.append(placeholder) |
2832 |
|
2833 |
partno+=1 |
2834 |
else: |
2835 |
newvalue.append(subpart) |
2836 |
part.value = newvalue |
2837 |
|
2838 |
|
2839 |
if 0 == totpacketno: |
2840 |
return |
2841 |
|
2842 |
res = [p] |
2843 |
p.packetno = packetno |
2844 |
rec(p, res, "%d-" % packetno) |
2845 |
|
2846 |
outfile = None |
2847 |
|
2848 |
summaryfile = open(os.path.join(location, "%s-%d-summary.tex" % (infilename.replace(".", "-"), totpacketno)), 'w') |
2849 |
|
2850 |
print >> summaryfile, """ |
2851 |
\\begin{tabular}{l}""" |
2852 |
|
2853 |
fname = "" |
2854 |
|
2855 |
i = 0 |
2856 |
for ppart in res: |
2857 |
if location: |
2858 |
if outfile: |
2859 |
outfile.close() |
2860 |
if classnames: |
2861 |
num = 0 |
2862 |
if clsrefs.has_key(ppart.classname): |
2863 |
num = clsrefs[ppart.classname] |
2864 |
clsrefs[ppart.classname]+=1 |
2865 |
else: |
2866 |
clsrefs[ppart.classname]=1 |
2867 |
fname = "%s-%d-%s%d-%s-%d.tex" % (infilename.replace(".", "-"), totpacketno, origin, packetno, ppart.classname, num) |
2868 |
else: |
2869 |
fname = "%s%s.tex" % (origin, ppart.packetno) |
2870 |
outfile = open(os.path.join(location, fname), 'w') |
2871 |
else: |
2872 |
outfile = ofile |
2873 |
print >> outfile, LaTeX_escape("\pkttab{%s%s}{%s %s}{\n" % (origin, ppart.packetno, ppart.datatype, ppart.description)) |
2874 |
|
2875 |
|
2876 |
s = "" |
2877 |
offset = 0 |
2878 |
if type([]) == type(ppart.value): |
2879 |
for subpart in ppart.value: |
2880 |
if type("") == type(subpart): |
2881 |
print >> outfile, LaTeX_escape("(str)&&&&%s\\\\" % (subpart)) |
2882 |
else: |
2883 |
print >> outfile, LaTeX_escape("%d & %s" % (offset, |
2884 |
subpart.latexvalue(offset=offset))) |
2885 |
offset+=len(subpart) |
2886 |
|
2887 |
else: |
2888 |
s = "off & %s & %s & " % (ppart.datatype, |
2889 |
ppart.description) |
2890 |
if None != ppart.knvalue: |
2891 |
s+=str(ppart.knvalue) |
2892 |
s+="& %s \\\\" % ppart.value |
2893 |
print >> outfile, LaTeX_escape(s) |
2894 |
print >> outfile, "}\n" |
2895 |
if id(ppart) != id(res[-1:][0]): |
2896 |
print >> summaryfile, "\input{%s}\\\\[\\betweenpktheight]" % os.path.join("figures", "pktfigs", fname) |
2897 |
else: |
2898 |
print >> summaryfile, "\input{%s}\\\\" % os.path.join("figures", "pktfigs", fname) |
2899 |
|
2900 |
print >> summaryfile, """\n\\end{tabular}""" |
2901 |
|
2902 |
|
2903 |
|
2904 |
|
2905 |
|
2906 |
|
2907 |
def parse_rdpproxy(infile, outfile, outputformat, location, |
2908 |
classnames, infilename, wantedchannels, quiet): |
2909 |
pktre = re.compile("#([0-9]*?), #([0-9]*?) from (Server|Client), type (TPKT|RDP5), l: ([0-9]*), ") |
2910 |
databeginre = re.compile("^0000 [0-9]{2} ") |
2911 |
line = infile.readline() |
2912 |
while line: |
2913 |
mo = pktre.search(line) |
2914 |
if None != mo: |
2915 |
headerline = line |
2916 |
totpacketno = int(mo.group(1)) |
2917 |
partpacketno = int(mo.group(2)) |
2918 |
part = mo.group(3) |
2919 |
pkttype = mo.group(4) |
2920 |
pktlength = int(mo.group(5)) |
2921 |
line = infile.readline() |
2922 |
while None == databeginre.search(line): # Unknown data, print. |
2923 |
line = infile.readline() |
2924 |
# We are now expecting pktlength bytes of data |
2925 |
data = line[5:53] |
2926 |
lines = pktlength / 16 |
2927 |
if pktlength % 16: |
2928 |
lines+=1 |
2929 |
lines-=1 |
2930 |
for i in range(lines): |
2931 |
thisdata = infile.readline()[5:53] |
2932 |
data+= thisdata |
2933 |
data = map(lambda x: string.atoi(x, 16), data.strip().split(' ')) |
2934 |
remaining = [] |
2935 |
if "TPKT" == pkttype: |
2936 |
p = TPKT("from %s" % part) |
2937 |
remaining = p.parse(data) |
2938 |
elif "RDP5" == pkttype: |
2939 |
p = RDP5Packet("from %s" % part) |
2940 |
remaining = p.parse(data) |
2941 |
global currentchannel |
2942 |
if 0 < len(wantedchannels) and currentchannel not in wantedchannels: |
2943 |
line = infile.readline() |
2944 |
continue |
2945 |
currentchannel = 0 |
2946 |
if "TBL" == outputformat: |
2947 |
create_tbl(outfile, p, part, totpacketno, partpacketno, location, classnames, infilename) |
2948 |
elif "LATEX" == outputformat: |
2949 |
create_latex(outfile, p, part, totpacketno, partpacketno, location, classnames, infilename) |
2950 |
else: |
2951 |
if not quiet: |
2952 |
outfile.write(headerline) |
2953 |
print >> outfile, p |
2954 |
if 0 < len(remaining): |
2955 |
rempkt = PacketPart("Remaining data") |
2956 |
rempkt.parse(remaining) |
2957 |
print >> outfile, rempkt |
2958 |
|
2959 |
else: # Unknown data line, just print it out. |
2960 |
if not quiet and "TXT" == outputformat: |
2961 |
outfile.write("Unknown data: %s" % line) |
2962 |
|
2963 |
outfile.flush() |
2964 |
line = infile.readline() |
2965 |
|
2966 |
|
2967 |
|
2968 |
def print_usage(progname): |
2969 |
print "%s <infile> <outfile>" % progname |
2970 |
print "<infile> and <outfile> may be '-' to use stdin/stdout" |
2971 |
print |
2972 |
print "OPTIONS is zero or more of the following:" |
2973 |
print "-f <outputformat> specifies that another format than text is wanted." |
2974 |
print " Possible formats are TXT (default), TBL and LATEX" |
2975 |
print "-l Specifies where the files produced by the TBL and LATEX formats should be written." |
2976 |
print " When this flag is used, outfile can be left out" |
2977 |
print "-n Use the names of the classes when printing out TBL and LATEX" |
2978 |
print "-c <channels> Print only output from specific channels." |
2979 |
print "-q Be quiet." |
2980 |
print "--help Print this not very helpful message :-)" |
2981 |
print |
2982 |
|
2983 |
if '__main__' == __name__: |
2984 |
now = time.time() |
2985 |
optlist, args = getopt.getopt(sys.argv[1:], 'f:l:ni:c:q') |
2986 |
|
2987 |
outputformat = "TXT" |
2988 |
location = None |
2989 |
classnames = None |
2990 |
ltxindex_out = None |
2991 |
channels = [] |
2992 |
quiet = 0 |
2993 |
for arg, opt in optlist: |
2994 |
if '-f' == arg: |
2995 |
outputformat = opt |
2996 |
if '-l' == arg: |
2997 |
location = opt |
2998 |
if '-n' == arg: |
2999 |
classnames = 1 |
3000 |
if '-c' == arg: |
3001 |
channels = map(int, opt.split(',')) |
3002 |
if '-q' == arg: |
3003 |
quiet = 1 |
3004 |
if '--help' == arg: |
3005 |
print_usage(sys.argv[0]) |
3006 |
sys.exit(0) |
3007 |
|
3008 |
if len(args) < 2 and not location: |
3009 |
print_usage(sys.argv[0]) |
3010 |
sys.exit(0) |
3011 |
|
3012 |
infile = sys.stdin |
3013 |
outfile = sys.stdout |
3014 |
|
3015 |
infilename = "stdin" |
3016 |
|
3017 |
if '-' != args[0]: |
3018 |
infilename = os.path.basename(args[0]) |
3019 |
infile = open(args[0], 'r') |
3020 |
if not location and '-' != args[1]: |
3021 |
outfile = open(args[1], 'w') |
3022 |
|
3023 |
parse_rdpproxy(infile, outfile, outputformat, location, |
3024 |
classnames, infilename, channels, quiet) |
3025 |
|
3026 |
print "Total processing time: %.2f seconds" % (time.time() - now) |
3027 |
|
3028 |
if sys.stdin != outfile: |
3029 |
infile.close() |
3030 |
if sys.stdout != outfile: |
3031 |
outfile.close() |
3032 |
|
3033 |
|
3034 |
# sys.argv = ["ARGL!", '/home/forsberg/xjobb/sniff/w2ktsk.1.out', '/home/forsberg/xjobb/rdpproxy/p.out'] |