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