/[rdesktop]/sourceforge.net/trunk/rdpproxy/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 /sourceforge.net/trunk/rdpproxy/pparser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 430 - (show annotations)
Mon Jun 30 08:59:07 2003 UTC (20 years, 9 months ago) by forsberg
File MIME type: text/x-python
File size: 105836 byte(s)
This commit was generated by cvs2svn to compensate for changes in r428,
which included commits to RCS files with non-trunk default branches.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26