/[rdesktop]/jpeg/rdpproxy/trunk/pparser.py
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /jpeg/rdpproxy/trunk/pparser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (show annotations)
Mon Jul 20 16:45:11 2009 UTC (14 years, 9 months ago) by dpavlin
File MIME type: text/x-python
File size: 105879 byte(s)
branch for integration of Daniel Jarboe <daniel.jarboe(at)gmail.com>
patches for jpeg
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']

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26