aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmproxy/console/contentview.py20
-rw-r--r--libmproxy/console/help.py4
-rw-r--r--libmproxy/contrib/wbxml/ASCommandResponse.py67
-rw-r--r--libmproxy/contrib/wbxml/ASWBXML.py897
-rw-r--r--libmproxy/contrib/wbxml/ASWBXMLByteQueue.py97
-rw-r--r--libmproxy/contrib/wbxml/ASWBXMLCodePage.py46
-rw-r--r--libmproxy/contrib/wbxml/GlobalTokens.py44
-rw-r--r--libmproxy/contrib/wbxml/InvalidDataException.py25
-rw-r--r--libmproxy/contrib/wbxml/__init__.py0
9 files changed, 1200 insertions, 0 deletions
diff --git a/libmproxy/console/contentview.py b/libmproxy/console/contentview.py
index 5f3e17fe..b1b99bb6 100644
--- a/libmproxy/console/contentview.py
+++ b/libmproxy/console/contentview.py
@@ -8,6 +8,7 @@ import netlib.utils
from . import common
from .. import utils, encoding, flow
from ..contrib import jsbeautifier, html2text
+from ..contrib.wbxml.ASCommandResponse import ASCommandResponse
try:
import pyamf
from pyamf import remoting, flex
@@ -426,12 +427,31 @@ class ViewProtobuf:
txt = _view_text(decoded[:limit], len(decoded), limit)
return "Protobuf", txt
+class ViewWBXML:
+ name = "WBXML"
+ prompt = ("wbxml", "w")
+ content_types = [
+ "application/vnd.wap.wbxml",
+ "application/vnd.ms-sync.wbxml"
+ ]
+
+ def __call__(self, hdrs, content, limit):
+
+ try:
+ parser = ASCommandResponse(content)
+ parsedContent = parser.xmlString
+ txt = _view_text(parsedContent, len(parsedContent), limit)
+ return "WBXML", txt
+ except:
+ return None
+
views = [
ViewAuto(),
ViewRaw(),
ViewHex(),
ViewJSON(),
ViewXML(),
+ ViewWBXML(),
ViewHTML(),
ViewHTMLOutline(),
ViewJavaScript(),
diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py
index bd7217e1..3fd216b5 100644
--- a/libmproxy/console/help.py
+++ b/libmproxy/console/help.py
@@ -79,6 +79,10 @@ class HelpView(urwid.ListBox):
[("text", ": XML")]
),
(None,
+ common.highlight_key("wbxml", "w") +
+ [("text", ": WBXML")]
+ ),
+ (None,
common.highlight_key("amf", "f") +
[("text", ": AMF (requires PyAMF)")]
),
diff --git a/libmproxy/contrib/wbxml/ASCommandResponse.py b/libmproxy/contrib/wbxml/ASCommandResponse.py
new file mode 100644
index 00000000..3938396f
--- /dev/null
+++ b/libmproxy/contrib/wbxml/ASCommandResponse.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: ASCommandResponse.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+from ASWBXML import ASWBXML
+import logging
+
+class ASCommandResponse:
+
+ def __init__(self, response):
+ self.wbxmlBody = response
+ try:
+ if ( len(response) > 0):
+ self.xmlString = self.decodeWBXML(self.wbxmlBody)
+ else:
+ logging.error("Empty WBXML body passed")
+ except Exception as e:
+ logging.error("Error: {0}".format(e.message))
+ self.xmlString = None
+
+ def getWBXMLBytes(self):
+ return self.wbxmlBytes
+
+ def getXMLString(self):
+ return self.xmlString
+
+ def decodeWBXML(self, body):
+ self.instance = ASWBXML()
+ self.instance.loadBytes(body)
+ return self.instance.getXml()
+
+if __name__ == "__main__":
+ import os
+ logging.basicConfig(level=logging.INFO)
+
+ projectDir = os.path.dirname(os.path.realpath("."))
+ samplesDir = os.path.join(projectDir, "Samples/")
+ listOfSamples = os.listdir(samplesDir)
+
+ for filename in listOfSamples:
+ byteWBXML = open(samplesDir + os.sep + filename, "rb").read()
+
+ logging.info("-"*100)
+ logging.info(filename)
+ logging.info("-"*100)
+ instance = ASCommandResponse(byteWBXML)
+ logging.info(instance.xmlString)
+ \ No newline at end of file
diff --git a/libmproxy/contrib/wbxml/ASWBXML.py b/libmproxy/contrib/wbxml/ASWBXML.py
new file mode 100644
index 00000000..08f9fcea
--- /dev/null
+++ b/libmproxy/contrib/wbxml/ASWBXML.py
@@ -0,0 +1,897 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: ASWBXML.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+import xml.dom.minidom
+import logging
+
+from ASWBXMLCodePage import ASWBXMLCodePage
+from ASWBXMLByteQueue import ASWBXMLByteQueue
+from GlobalTokens import GlobalTokens
+from InvalidDataException import InvalidDataException
+
+class ASWBXML:
+ versionByte = 0x03
+ publicIdentifierByte = 0x01
+ characterSetByte = 0x6A
+ stringTableLengthByte = 0x00
+
+ def __init__(self):
+
+ # empty on init
+ self.xmlDoc = xml.dom.minidom.Document()
+ self.currentCodePage = 0
+ self.defaultCodePage = -1
+
+ # Load up code pages
+ # Currently there are 25 code pages as per MS-ASWBXML
+ self.codePages = []
+
+ # region Code Page Initialization
+ # Code Page 0: AirSync
+ # region AirSync Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "AirSync:"
+ page.xmlns = "airsync"
+
+ page.addToken(0x05, "Sync")
+ page.addToken(0x06, "Responses")
+ page.addToken(0x07, "Add")
+ page.addToken(0x08, "Change")
+ page.addToken(0x09, "Delete")
+ page.addToken(0x0A, "Fetch")
+ page.addToken(0x0B, "SyncKey")
+ page.addToken(0x0C, "ClientId")
+ page.addToken(0x0D, "ServerId")
+ page.addToken(0x0E, "Status")
+ page.addToken(0x0F, "Collection")
+ page.addToken(0x10, "Class")
+ page.addToken(0x12, "CollectionId")
+ page.addToken(0x13, "GetChanges")
+ page.addToken(0x14, "MoreAvailable")
+ page.addToken(0x15, "WindowSize")
+ page.addToken(0x16, "Commands")
+ page.addToken(0x17, "Options")
+ page.addToken(0x18, "FilterType")
+ page.addToken(0x1B, "Conflict")
+ page.addToken(0x1C, "Collections")
+ page.addToken(0x1D, "ApplicationData")
+ page.addToken(0x1E, "DeletesAsMoves")
+ page.addToken(0x20, "Supported")
+ page.addToken(0x21, "SoftDelete")
+ page.addToken(0x22, "MIMESupport")
+ page.addToken(0x23, "MIMETruncation")
+ page.addToken(0x24, "Wait")
+ page.addToken(0x25, "Limit")
+ page.addToken(0x26, "Partial")
+ page.addToken(0x27, "ConversationMode")
+ page.addToken(0x28, "MaxItems")
+ page.addToken(0x29, "HeartbeatInterval")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 1: Contacts
+ # region Contacts Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Contacts:"
+ page.xmlns = "contacts"
+
+ page.addToken(0x05, "Anniversary")
+ page.addToken(0x06, "AssistantName")
+ page.addToken(0x07, "AssistantTelephoneNumber")
+ page.addToken(0x08, "Birthday")
+ page.addToken(0x0C, "Business2PhoneNumber")
+ page.addToken(0x0D, "BusinessCity")
+ page.addToken(0x0E, "BusinessCountry")
+ page.addToken(0x0F, "BusinessPostalCode")
+ page.addToken(0x10, "BusinessState")
+ page.addToken(0x11, "BusinessStreet")
+ page.addToken(0x12, "BusinessFaxNumber")
+ page.addToken(0x13, "BusinessPhoneNumber")
+ page.addToken(0x14, "CarPhoneNumber")
+ page.addToken(0x15, "Categories")
+ page.addToken(0x16, "Category")
+ page.addToken(0x17, "Children")
+ page.addToken(0x18, "Child")
+ page.addToken(0x19, "CompanyName")
+ page.addToken(0x1A, "Department")
+ page.addToken(0x1B, "Email1Address")
+ page.addToken(0x1C, "Email2Address")
+ page.addToken(0x1D, "Email3Address")
+ page.addToken(0x1E, "FileAs")
+ page.addToken(0x1F, "FirstName")
+ page.addToken(0x20, "Home2PhoneNumber")
+ page.addToken(0x21, "HomeCity")
+ page.addToken(0x22, "HomeCountry")
+ page.addToken(0x23, "HomePostalCode")
+ page.addToken(0x24, "HomeState")
+ page.addToken(0x25, "HomeStreet")
+ page.addToken(0x26, "HomeFaxNumber")
+ page.addToken(0x27, "HomePhoneNumber")
+ page.addToken(0x28, "JobTitle")
+ page.addToken(0x29, "LastName")
+ page.addToken(0x2A, "MiddleName")
+ page.addToken(0x2B, "MobilePhoneNumber")
+ page.addToken(0x2C, "OfficeLocation")
+ page.addToken(0x2D, "OtherCity")
+ page.addToken(0x2E, "OtherCountry")
+ page.addToken(0x2F, "OtherPostalCode")
+ page.addToken(0x30, "OtherState")
+ page.addToken(0x31, "OtherStreet")
+ page.addToken(0x32, "PagerNumber")
+ page.addToken(0x33, "RadioPhoneNumber")
+ page.addToken(0x34, "Spouse")
+ page.addToken(0x35, "Suffix")
+ page.addToken(0x36, "Title")
+ page.addToken(0x37, "Webpage")
+ page.addToken(0x38, "YomiCompanyName")
+ page.addToken(0x39, "YomiFirstName")
+ page.addToken(0x3A, "YomiLastName")
+ page.addToken(0x3C, "Picture")
+ page.addToken(0x3D, "Alias")
+ page.addToken(0x3E, "WeightedRank")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 2: Email
+ # region Email Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Email:"
+ page.xmlns = "email"
+
+ page.addToken(0x0F, "DateReceived")
+ page.addToken(0x11, "DisplayTo")
+ page.addToken(0x12, "Importance")
+ page.addToken(0x13, "MessageClass")
+ page.addToken(0x14, "Subject")
+ page.addToken(0x15, "Read")
+ page.addToken(0x16, "To")
+ page.addToken(0x17, "CC")
+ page.addToken(0x18, "From")
+ page.addToken(0x19, "ReplyTo")
+ page.addToken(0x1A, "AllDayEvent")
+ page.addToken(0x1B, "Categories")
+ page.addToken(0x1C, "Category")
+ page.addToken(0x1D, "DTStamp")
+ page.addToken(0x1E, "EndTime")
+ page.addToken(0x1F, "InstanceType")
+ page.addToken(0x20, "BusyStatus")
+ page.addToken(0x21, "Location")
+ page.addToken(0x22, "MeetingRequest")
+ page.addToken(0x23, "Organizer")
+ page.addToken(0x24, "RecurrenceId")
+ page.addToken(0x25, "Reminder")
+ page.addToken(0x26, "ResponseRequested")
+ page.addToken(0x27, "Recurrences")
+ page.addToken(0x28, "Recurrence")
+ page.addToken(0x29, "Recurrence_Type")
+ page.addToken(0x2A, "Recurrence_Until")
+ page.addToken(0x2B, "Recurrence_Occurrences")
+ page.addToken(0x2C, "Recurrence_Interval")
+ page.addToken(0x2D, "Recurrence_DayOfWeek")
+ page.addToken(0x2E, "Recurrence_DayOfMonth")
+ page.addToken(0x2F, "Recurrence_WeekOfMonth")
+ page.addToken(0x30, "Recurrence_MonthOfYear")
+ page.addToken(0x31, "StartTime")
+ page.addToken(0x32, "Sensitivity")
+ page.addToken(0x33, "TimeZone")
+ page.addToken(0x34, "GlobalObjId")
+ page.addToken(0x35, "ThreadTopic")
+ page.addToken(0x39, "InternetCPID")
+ page.addToken(0x3A, "Flag")
+ page.addToken(0x3B, "FlagStatus")
+ page.addToken(0x3C, "ContentClass")
+ page.addToken(0x3D, "FlagType")
+ page.addToken(0x3E, "CompleteTime")
+ page.addToken(0x3F, "DisallowNewTimeProposal")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 3: AirNotify - retired
+ # region AirNotify Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = ""
+ page.xmlns = ""
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 4: Calendar
+ # region Calendar Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Calendar:"
+ page.xmlns = "calendar"
+
+ page.addToken(0x05, "TimeZone")
+ page.addToken(0x06, "AllDayEvent")
+ page.addToken(0x07, "Attendees")
+ page.addToken(0x08, "Attendee")
+ page.addToken(0x09, "Attendee_Email")
+ page.addToken(0x0A, "Attendee_Name")
+ page.addToken(0x0D, "BusyStatus")
+ page.addToken(0x0E, "Categories")
+ page.addToken(0x0F, "Category")
+ page.addToken(0x11, "DTStamp")
+ page.addToken(0x12, "EndTime")
+ page.addToken(0x13, "Exception")
+ page.addToken(0x14, "Exceptions")
+ page.addToken(0x15, "Exception_Deleted")
+ page.addToken(0x16, "Exception_StartTime")
+ page.addToken(0x17, "Location")
+ page.addToken(0x18, "MeetingStatus")
+ page.addToken(0x19, "Organizer_Email")
+ page.addToken(0x1A, "Organizer_Name")
+ page.addToken(0x1B, "Recurrence")
+ page.addToken(0x1C, "Recurrence_Type")
+ page.addToken(0x1D, "Recurrence_Until")
+ page.addToken(0x1E, "Recurrence_Occurrences")
+ page.addToken(0x1F, "Recurrence_Interval")
+ page.addToken(0x20, "Recurrence_DayOfWeek")
+ page.addToken(0x21, "Recurrence_DayOfMonth")
+ page.addToken(0x22, "Recurrence_WeekOfMonth")
+ page.addToken(0x23, "Recurrence_MonthOfYear")
+ page.addToken(0x24, "Reminder")
+ page.addToken(0x25, "Sensitivity")
+ page.addToken(0x26, "Subject")
+ page.addToken(0x27, "StartTime")
+ page.addToken(0x28, "UID")
+ page.addToken(0x29, "Attendee_Status")
+ page.addToken(0x2A, "Attendee_Type")
+ page.addToken(0x33, "DisallowNewTimeProposal")
+ page.addToken(0x34, "ResponseRequested")
+ page.addToken(0x35, "AppointmentReplyTime")
+ page.addToken(0x36, "ResponseType")
+ page.addToken(0x37, "CalendarType")
+ page.addToken(0x38, "IsLeapMonth")
+ page.addToken(0x39, "FirstDayOfWeek")
+ page.addToken(0x3A, "OnlineMeetingConfLink")
+ page.addToken(0x3B, "OnlineMeetingExternalLink")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 5: Move
+ # region Move Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Move:"
+ page.xmlns = "move"
+
+ page.addToken(0x05, "MoveItems")
+ page.addToken(0x06, "Move")
+ page.addToken(0x07, "SrcMsgId")
+ page.addToken(0x08, "SrcFldId")
+ page.addToken(0x09, "DstFldId")
+ page.addToken(0x0A, "Response")
+ page.addToken(0x0B, "Status")
+ page.addToken(0x0C, "DstMsgId")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 6: ItemEstimate
+ # region ItemEstimate Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "GetItemEstimate:"
+ page.xmlns = "getitemestimate"
+
+ page.addToken(0x05, "GetItemEstimate")
+ page.addToken(0x06, "Version")
+ page.addToken(0x07, "Collections")
+ page.addToken(0x08, "Collection")
+ page.addToken(0x09, "Class")
+ page.addToken(0x0A, "CollectionId")
+ page.addToken(0x0B, "DateTime")
+ page.addToken(0x0C, "Estimate")
+ page.addToken(0x0D, "Response")
+ page.addToken(0x0E, "Status")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 7: FolderHierarchy
+ # region FolderHierarchy Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "FolderHierarchy:"
+ page.xmlns = "folderhierarchy"
+
+ page.addToken(0x07, "DisplayName")
+ page.addToken(0x08, "ServerId")
+ page.addToken(0x09, "ParentId")
+ page.addToken(0x0A, "Type")
+ page.addToken(0x0C, "Status")
+ page.addToken(0x0E, "Changes")
+ page.addToken(0x0F, "Add")
+ page.addToken(0x10, "Delete")
+ page.addToken(0x11, "Update")
+ page.addToken(0x12, "SyncKey")
+ page.addToken(0x13, "FolderCreate")
+ page.addToken(0x14, "FolderDelete")
+ page.addToken(0x15, "FolderUpdate")
+ page.addToken(0x16, "FolderSync")
+ page.addToken(0x17, "Count")
+
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 8: MeetingResponse
+ # region MeetingResponse Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "MeetingResponse:"
+ page.xmlns = "meetingresponse"
+
+ page.addToken(0x05, "CalendarId")
+ page.addToken(0x06, "CollectionId")
+ page.addToken(0x07, "MeetingResponse")
+ page.addToken(0x08, "RequestId")
+ page.addToken(0x09, "Request")
+ page.addToken(0x0A, "Result")
+ page.addToken(0x0B, "Status")
+ page.addToken(0x0C, "UserResponse")
+ page.addToken(0x0E, "InstanceId")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 9: Tasks
+ # region Tasks Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Tasks:"
+ page.xmlns = "tasks"
+
+ page.addToken(0x08, "Categories")
+ page.addToken(0x09, "Category")
+ page.addToken(0x0A, "Complete")
+ page.addToken(0x0B, "DateCompleted")
+ page.addToken(0x0C, "DueDate")
+ page.addToken(0x0D, "UTCDueDate")
+ page.addToken(0x0E, "Importance")
+ page.addToken(0x0F, "Recurrence")
+ page.addToken(0x10, "Recurrence_Type")
+ page.addToken(0x11, "Recurrence_Start")
+ page.addToken(0x12, "Recurrence_Until")
+ page.addToken(0x13, "Recurrence_Occurrences")
+ page.addToken(0x14, "Recurrence_Interval")
+ page.addToken(0x15, "Recurrence_DayOfMonth")
+ page.addToken(0x16, "Recurrence_DayOfWeek")
+ page.addToken(0x17, "Recurrence_WeekOfMonth")
+ page.addToken(0x18, "Recurrence_MonthOfYear")
+ page.addToken(0x19, "Recurrence_Regenerate")
+ page.addToken(0x1A, "Recurrence_DeadOccur")
+ page.addToken(0x1B, "ReminderSet")
+ page.addToken(0x1C, "ReminderTime")
+ page.addToken(0x1D, "Sensitivity")
+ page.addToken(0x1E, "StartDate")
+ page.addToken(0x1F, "UTCStartDate")
+ page.addToken(0x20, "Subject")
+ page.addToken(0x22, "OrdinalDate")
+ page.addToken(0x23, "SubOrdinalDate")
+ page.addToken(0x24, "CalendarType")
+ page.addToken(0x25, "IsLeapMonth")
+ page.addToken(0x26, "FirstDayOfWeek")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 10: ResolveRecipients
+ # region ResolveRecipients Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "ResolveRecipients:"
+ page.xmlns = "resolverecipients"
+
+ page.addToken(0x05, "ResolveRecipients")
+ page.addToken(0x06, "Response")
+ page.addToken(0x07, "Status")
+ page.addToken(0x08, "Type")
+ page.addToken(0x09, "Recipient")
+ page.addToken(0x0A, "DisplayName")
+ page.addToken(0x0B, "EmailAddress")
+ page.addToken(0x0C, "Certificates")
+ page.addToken(0x0D, "Certificate")
+ page.addToken(0x0E, "MiniCertificate")
+ page.addToken(0x0F, "Options")
+ page.addToken(0x10, "To")
+ page.addToken(0x11, "CertificateRetrieval")
+ page.addToken(0x12, "RecipientCount")
+ page.addToken(0x13, "MaxCertificates")
+ page.addToken(0x14, "MaxAmbiguousRecipients")
+ page.addToken(0x15, "CertificateCount")
+ page.addToken(0x16, "Availability")
+ page.addToken(0x17, "StartTime")
+ page.addToken(0x18, "EndTime")
+ page.addToken(0x19, "MergedFreeBusy")
+ page.addToken(0x1A, "Picture")
+ page.addToken(0x1B, "MaxSize")
+ page.addToken(0x1C, "Data")
+ page.addToken(0x1D, "MaxPictures")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 11: ValidateCert
+ # region ValidateCert Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "ValidateCert:"
+ page.xmlns = "validatecert"
+
+ page.addToken(0x05, "ValidateCert")
+ page.addToken(0x06, "Certificates")
+ page.addToken(0x07, "Certificate")
+ page.addToken(0x08, "CertificateChain")
+ page.addToken(0x09, "CheckCRL")
+ page.addToken(0x0A, "Status")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 12: Contacts2
+ # region Contacts2 Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Contacts2:"
+ page.xmlns = "contacts2"
+
+ page.addToken(0x05, "CustomerId")
+ page.addToken(0x06, "GovernmentId")
+ page.addToken(0x07, "IMAddress")
+ page.addToken(0x08, "IMAddress2")
+ page.addToken(0x09, "IMAddress3")
+ page.addToken(0x0A, "ManagerName")
+ page.addToken(0x0B, "CompanyMainPhone")
+ page.addToken(0x0C, "AccountName")
+ page.addToken(0x0D, "NickName")
+ page.addToken(0x0E, "MMS")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 13: Ping
+ # region Ping Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Ping:"
+ page.xmlns = "ping"
+
+ page.addToken(0x05, "Ping")
+ page.addToken(0x06, "AutdState") # Per MS-ASWBXML, this tag is not used by protocol
+ page.addToken(0x07, "Status")
+ page.addToken(0x08, "HeartbeatInterval")
+ page.addToken(0x09, "Folders")
+ page.addToken(0x0A, "Folder")
+ page.addToken(0x0B, "Id")
+ page.addToken(0x0C, "Class")
+ page.addToken(0x0D, "MaxFolders")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 14: Provision
+ # region Provision Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Provision:"
+ page.xmlns = "provision"
+
+ page.addToken(0x05, "Provision")
+ page.addToken(0x06, "Policies")
+ page.addToken(0x07, "Policy")
+ page.addToken(0x08, "PolicyType")
+ page.addToken(0x09, "PolicyKey")
+ page.addToken(0x0A, "Data")
+ page.addToken(0x0B, "Status")
+ page.addToken(0x0C, "RemoteWipe")
+ page.addToken(0x0D, "EASProvisionDoc")
+ page.addToken(0x0E, "DevicePasswordEnabled")
+ page.addToken(0x0F, "AlphanumericDevicePasswordRequired")
+ page.addToken(0x10, "RequireStorageCardEncryption")
+ page.addToken(0x11, "PasswordRecoveryEnabled")
+ page.addToken(0x13, "AttachmentsEnabled")
+ page.addToken(0x14, "MinDevicePasswordLength")
+ page.addToken(0x15, "MaxInactivityTimeDeviceLock")
+ page.addToken(0x16, "MaxDevicePasswordFailedAttempts")
+ page.addToken(0x17, "MaxAttachmentSize")
+ page.addToken(0x18, "AllowSimpleDevicePassword")
+ page.addToken(0x19, "DevicePasswordExpiration")
+ page.addToken(0x1A, "DevicePasswordHistory")
+ page.addToken(0x1B, "AllowStorageCard")
+ page.addToken(0x1C, "AllowCamera")
+ page.addToken(0x1D, "RequireDeviceEncryption")
+ page.addToken(0x1E, "AllowUnsignedApplications")
+ page.addToken(0x1F, "AllowUnsignedInstallationPackages")
+ page.addToken(0x20, "MinDevicePasswordComplexCharacters")
+ page.addToken(0x21, "AllowWiFi")
+ page.addToken(0x22, "AllowTextMessaging")
+ page.addToken(0x23, "AllowPOPIMAPEmail")
+ page.addToken(0x24, "AllowBluetooth")
+ page.addToken(0x25, "AllowIrDA")
+ page.addToken(0x26, "RequireManualSyncWhenRoaming")
+ page.addToken(0x27, "AllowDesktopSync")
+ page.addToken(0x28, "MaxCalendarAgeFilter")
+ page.addToken(0x29, "AllowHTMLEmail")
+ page.addToken(0x2A, "MaxEmailAgeFilter")
+ page.addToken(0x2B, "MaxEmailBodyTruncationSize")
+ page.addToken(0x2C, "MaxEmailHTMLBodyTruncationSize")
+ page.addToken(0x2D, "RequireSignedSMIMEMessages")
+ page.addToken(0x2E, "RequireEncryptedSMIMEMessages")
+ page.addToken(0x2F, "RequireSignedSMIMEAlgorithm")
+ page.addToken(0x30, "RequireEncryptionSMIMEAlgorithm")
+ page.addToken(0x31, "AllowSMIMEEncryptionAlgorithmNegotiation")
+ page.addToken(0x32, "AllowSMIMESoftCerts")
+ page.addToken(0x33, "AllowBrowser")
+ page.addToken(0x34, "AllowConsumerEmail")
+ page.addToken(0x35, "AllowRemoteDesktop")
+ page.addToken(0x36, "AllowInternetSharing")
+ page.addToken(0x37, "UnapprovedInROMApplicationList")
+ page.addToken(0x38, "ApplicationName")
+ page.addToken(0x39, "ApprovedApplicationList")
+ page.addToken(0x3A, "Hash")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 15: Search
+ # region Search Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Search:"
+ page.xmlns = "search"
+
+ page.addToken(0x05, "Search")
+ page.addToken(0x07, "Store")
+ page.addToken(0x08, "Name")
+ page.addToken(0x09, "Query")
+ page.addToken(0x0A, "Options")
+ page.addToken(0x0B, "Range")
+ page.addToken(0x0C, "Status")
+ page.addToken(0x0D, "Response")
+ page.addToken(0x0E, "Result")
+ page.addToken(0x0F, "Properties")
+ page.addToken(0x10, "Total")
+ page.addToken(0x11, "EqualTo")
+ page.addToken(0x12, "Value")
+ page.addToken(0x13, "And")
+ page.addToken(0x14, "Or")
+ page.addToken(0x15, "FreeText")
+ page.addToken(0x17, "DeepTraversal")
+ page.addToken(0x18, "LongId")
+ page.addToken(0x19, "RebuildResults")
+ page.addToken(0x1A, "LessThan")
+ page.addToken(0x1B, "GreaterThan")
+ page.addToken(0x1E, "UserName")
+ page.addToken(0x1F, "Password")
+ page.addToken(0x20, "ConversationId")
+ page.addToken(0x21, "Picture")
+ page.addToken(0x22, "MaxSize")
+ page.addToken(0x23, "MaxPictures")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 16: GAL
+ # region GAL Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "GAL:"
+ page.xmlns = "gal"
+
+ page.addToken(0x05, "DisplayName")
+ page.addToken(0x06, "Phone")
+ page.addToken(0x07, "Office")
+ page.addToken(0x08, "Title")
+ page.addToken(0x09, "Company")
+ page.addToken(0x0A, "Alias")
+ page.addToken(0x0B, "FirstName")
+ page.addToken(0x0C, "LastName")
+ page.addToken(0x0D, "HomePhone")
+ page.addToken(0x0E, "MobilePhone")
+ page.addToken(0x0F, "EmailAddress")
+ page.addToken(0x10, "Picture")
+ page.addToken(0x11, "Status")
+ page.addToken(0x12, "Data")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 17: AirSyncBase
+ # region AirSyncBase Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "AirSyncBase:"
+ page.xmlns = "airsyncbase"
+
+ page.addToken(0x05, "BodyPreference")
+ page.addToken(0x06, "Type")
+ page.addToken(0x07, "TruncationSize")
+ page.addToken(0x08, "AllOrNone")
+ page.addToken(0x0A, "Body")
+ page.addToken(0x0B, "Data")
+ page.addToken(0x0C, "EstimatedDataSize")
+ page.addToken(0x0D, "Truncated")
+ page.addToken(0x0E, "Attachments")
+ page.addToken(0x0F, "Attachment")
+ page.addToken(0x10, "DisplayName")
+ page.addToken(0x11, "FileReference")
+ page.addToken(0x12, "Method")
+ page.addToken(0x13, "ContentId")
+ page.addToken(0x14, "ContentLocation")
+ page.addToken(0x15, "IsInline")
+ page.addToken(0x16, "NativeBodyType")
+ page.addToken(0x17, "ContentType")
+ page.addToken(0x18, "Preview")
+ page.addToken(0x19, "BodyPartPreference")
+ page.addToken(0x1A, "BodyPart")
+ page.addToken(0x1B, "Status")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 18: Settings
+ # region Settings Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Settings:"
+ page.xmlns = "settings"
+
+ page.addToken(0x05, "Settings")
+ page.addToken(0x06, "Status")
+ page.addToken(0x07, "Get")
+ page.addToken(0x08, "Set")
+ page.addToken(0x09, "Oof")
+ page.addToken(0x0A, "OofState")
+ page.addToken(0x0B, "StartTime")
+ page.addToken(0x0C, "EndTime")
+ page.addToken(0x0D, "OofMessage")
+ page.addToken(0x0E, "AppliesToInternal")
+ page.addToken(0x0F, "AppliesToExternalKnown")
+ page.addToken(0x10, "AppliesToExternalUnknown")
+ page.addToken(0x11, "Enabled")
+ page.addToken(0x12, "ReplyMessage")
+ page.addToken(0x13, "BodyType")
+ page.addToken(0x14, "DevicePassword")
+ page.addToken(0x15, "Password")
+ page.addToken(0x16, "DeviceInformation")
+ page.addToken(0x17, "Model")
+ page.addToken(0x18, "IMEI")
+ page.addToken(0x19, "FriendlyName")
+ page.addToken(0x1A, "OS")
+ page.addToken(0x1B, "OSLanguage")
+ page.addToken(0x1C, "PhoneNumber")
+ page.addToken(0x1D, "UserInformation")
+ page.addToken(0x1E, "EmailAddresses")
+ page.addToken(0x1F, "SmtpAddress")
+ page.addToken(0x20, "UserAgent")
+ page.addToken(0x21, "EnableOutboundSMS")
+ page.addToken(0x22, "MobileOperator")
+ page.addToken(0x23, "PrimarySmtpAddress")
+ page.addToken(0x24, "Accounts")
+ page.addToken(0x25, "Account")
+ page.addToken(0x26, "AccountId")
+ page.addToken(0x27, "AccountName")
+ page.addToken(0x28, "UserDisplayName")
+ page.addToken(0x29, "SendDisabled")
+ page.addToken(0x2B, "RightsManagementInformation")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 19: DocumentLibrary
+ # region DocumentLibrary Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "DocumentLibrary:"
+ page.xmlns = "documentlibrary"
+
+ page.addToken(0x05, "LinkId")
+ page.addToken(0x06, "DisplayName")
+ page.addToken(0x07, "IsFolder")
+ page.addToken(0x08, "CreationDate")
+ page.addToken(0x09, "LastModifiedDate")
+ page.addToken(0x0A, "IsHidden")
+ page.addToken(0x0B, "ContentLength")
+ page.addToken(0x0C, "ContentType")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 20: ItemOperations
+ # region ItemOperations Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "ItemOperations:"
+ page.xmlns = "itemoperations"
+
+ page.addToken(0x05, "ItemOperations")
+ page.addToken(0x06, "Fetch")
+ page.addToken(0x07, "Store")
+ page.addToken(0x08, "Options")
+ page.addToken(0x09, "Range")
+ page.addToken(0x0A, "Total")
+ page.addToken(0x0B, "Properties")
+ page.addToken(0x0C, "Data")
+ page.addToken(0x0D, "Status")
+ page.addToken(0x0E, "Response")
+ page.addToken(0x0F, "Version")
+ page.addToken(0x10, "Schema")
+ page.addToken(0x11, "Part")
+ page.addToken(0x12, "EmptyFolderContents")
+ page.addToken(0x13, "DeleteSubFolders")
+ page.addToken(0x14, "UserName")
+ page.addToken(0x15, "Password")
+ page.addToken(0x16, "Move")
+ page.addToken(0x17, "DstFldId")
+ page.addToken(0x18, "ConversationId")
+ page.addToken(0x19, "MoveAlways")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 21: ComposeMail
+ # region ComposeMail Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "ComposeMail:"
+ page.xmlns = "composemail"
+
+ page.addToken(0x05, "SendMail")
+ page.addToken(0x06, "SmartForward")
+ page.addToken(0x07, "SmartReply")
+ page.addToken(0x08, "SaveInSentItems")
+ page.addToken(0x09, "ReplaceMime")
+ page.addToken(0x0B, "Source")
+ page.addToken(0x0C, "FolderId")
+ page.addToken(0x0D, "ItemId")
+ page.addToken(0x0E, "LongId")
+ page.addToken(0x0F, "InstanceId")
+ page.addToken(0x10, "MIME")
+ page.addToken(0x11, "ClientId")
+ page.addToken(0x12, "Status")
+ page.addToken(0x13, "AccountId")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 22: Email2
+ # region Email2 Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Email2:"
+ page.xmlns = "email2"
+
+ page.addToken(0x05, "UmCallerID")
+ page.addToken(0x06, "UmUserNotes")
+ page.addToken(0x07, "UmAttDuration")
+ page.addToken(0x08, "UmAttOrder")
+ page.addToken(0x09, "ConversationId")
+ page.addToken(0x0A, "ConversationIndex")
+ page.addToken(0x0B, "LastVerbExecuted")
+ page.addToken(0x0C, "LastVerbExecutionTime")
+ page.addToken(0x0D, "ReceivedAsBcc")
+ page.addToken(0x0E, "Sender")
+ page.addToken(0x0F, "CalendarType")
+ page.addToken(0x10, "IsLeapMonth")
+ page.addToken(0x11, "AccountId")
+ page.addToken(0x12, "FirstDayOfWeek")
+ page.addToken(0x13, "MeetingMessageType")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 23: Notes
+ # region Notes Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "Notes:"
+ page.xmlns = "notes"
+
+ page.addToken(0x05, "Subject")
+ page.addToken(0x06, "MessageClass")
+ page.addToken(0x07, "LastModifiedDate")
+ page.addToken(0x08, "Categories")
+ page.addToken(0x09, "Category")
+ self.codePages.append(page)
+ # endregion
+
+ # Code Page 24: RightsManagement
+ # region RightsManagement Code Page
+ page = ASWBXMLCodePage()
+ page.namespace = "RightsManagement:"
+ page.xmlns = "rightsmanagement"
+
+ page.addToken(0x05, "RightsManagementSupport")
+ page.addToken(0x06, "RightsManagementTemplates")
+ page.addToken(0x07, "RightsManagementTemplate")
+ page.addToken(0x08, "RightsManagementLicense")
+ page.addToken(0x09, "EditAllowed")
+ page.addToken(0x0A, "ReplyAllowed")
+ page.addToken(0x0B, "ReplyAllAllowed")
+ page.addToken(0x0C, "ForwardAllowed")
+ page.addToken(0x0D, "ModifyRecipientsAllowed")
+ page.addToken(0x0E, "ExtractAllowed")
+ page.addToken(0x0F, "PrintAllowed")
+ page.addToken(0x10, "ExportAllowed")
+ page.addToken(0x11, "ProgrammaticAccessAllowed")
+ page.addToken(0x12, "RMOwner")
+ page.addToken(0x13, "ContentExpiryDate")
+ page.addToken(0x14, "TemplateID")
+ page.addToken(0x15, "TemplateName")
+ page.addToken(0x16, "TemplateDescription")
+ page.addToken(0x17, "ContentOwner")
+ page.addToken(0x18, "RemoveRightsManagementDistribution")
+ self.codePages.append(page)
+ # endregion
+ # endregion
+
+ def loadXml(self, strXML):
+ # note xmlDoc has .childNodes and .parentNode
+ self.xmlDoc = xml.dom.minidom.parseString(strXML)
+
+ def getXml(self):
+ if (self.xmlDoc != None):
+ try:
+ return self.xmlDoc.toprettyxml(indent=" ", newl="\n")
+ except:
+ return self.xmlDoc.toxml()
+
+ def loadBytes(self, byteWBXML):
+
+ currentNode = self.xmlDoc
+
+ wbXMLBytes = ASWBXMLByteQueue(byteWBXML)
+ # Version is ignored
+ version = wbXMLBytes.dequeueAndLog()
+
+ # Public Identifier is ignored
+ publicId = wbXMLBytes.dequeueMultibyteInt()
+
+ logging.debug("Version: %d, Public Identifier: %d" % (version, publicId))
+
+ # Character set
+ # Currently only UTF-8 is supported, throw if something else
+ charset = wbXMLBytes.dequeueMultibyteInt()
+ if (charset != 0x6A):
+ raise InvalidDataException("ASWBXML only supports UTF-8 encoded XML.")
+
+ # String table length
+ # This should be 0, MS-ASWBXML does not use string tables
+ stringTableLength = wbXMLBytes.dequeueMultibyteInt()
+ if (stringTableLength != 0):
+ raise InvalidDataException("WBXML data contains a string table.")
+
+ # Now we should be at the body of the data.
+ # Add the declaration
+ unusedArray = [GlobalTokens.ENTITY, GlobalTokens.EXT_0, GlobalTokens.EXT_1, GlobalTokens.EXT_2, GlobalTokens.EXT_I_0, GlobalTokens.EXT_I_1, GlobalTokens.EXT_I_2, GlobalTokens.EXT_T_0, GlobalTokens.EXT_T_1, GlobalTokens.EXT_T_2, GlobalTokens.LITERAL, GlobalTokens.LITERAL_A, GlobalTokens.LITERAL_AC, GlobalTokens.LITERAL_C, GlobalTokens.PI, GlobalTokens.STR_T]
+
+ while ( wbXMLBytes.qsize() > 0):
+ currentByte = wbXMLBytes.dequeueAndLog()
+ if ( currentByte == GlobalTokens.SWITCH_PAGE ):
+ newCodePage = wbXMLBytes.dequeueAndLog()
+ if (newCodePage >= 0 and newCodePage < 25):
+ self.currentCodePage = newCodePage
+ else:
+ raise InvalidDataException("Unknown code page ID 0x{0:X} encountered in WBXML".format(currentByte))
+ elif ( currentByte == GlobalTokens.END ):
+ if (currentNode != None and currentNode.parentNode != None):
+ currentNode = currentNode.parentNode
+ else:
+ raise InvalidDataException("END global token encountered out of sequence")
+ break
+ elif ( currentByte == GlobalTokens.OPAQUE ):
+ CDATALength = wbXMLBytes.dequeueMultibyteInt()
+ newOpaqueNode = self.xmlDoc.createCDATASection(wbXMLBytes.dequeueString(CDATALength))
+ currentNode.appendChild(newOpaqueNode)
+
+ elif ( currentByte == GlobalTokens.STR_I ):
+ newTextNode = self.xmlDoc.createTextNode(wbXMLBytes.dequeueString())
+ currentNode.appendChild(newTextNode)
+
+ elif ( currentByte in unusedArray):
+ raise InvalidDataException("Encountered unknown global token 0x{0:X}.".format(currentByte))
+ else:
+ hasAttributes = (currentByte & 0x80) > 0
+ hasContent = (currentByte & 0x40) > 0
+
+ token = currentByte & 0x3F
+ if (hasAttributes):
+ raise InvalidDataException("Token 0x{0:X} has attributes.".format(token))
+
+ strTag = self.codePages[self.currentCodePage].getTag(token)
+ if (strTag == None):
+ strTag = "UNKNOWN_TAG_{0,2:X}".format(token)
+
+ newNode = self.xmlDoc.createElement(strTag)
+ # not sure if this should be set on every node or not
+ #newNode.setAttribute("xmlns", self.codePages[self.currentCodePage].xmlns)
+
+ currentNode.appendChild(newNode)
+
+ if (hasContent):
+ currentNode = newNode
+
+ logging.debug("Total bytes dequeued: %d" % wbXMLBytes.bytesDequeued)
diff --git a/libmproxy/contrib/wbxml/ASWBXMLByteQueue.py b/libmproxy/contrib/wbxml/ASWBXMLByteQueue.py
new file mode 100644
index 00000000..6c16edd4
--- /dev/null
+++ b/libmproxy/contrib/wbxml/ASWBXMLByteQueue.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: ASWBXMLByteQueue.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+from Queue import Queue
+import logging
+
+class ASWBXMLByteQueue(Queue):
+
+ def __init__(self, wbxmlBytes):
+
+ self.bytesDequeued = 0
+ self.bytesEnqueued = 0
+
+ Queue.__init__(self)
+
+ for byte in wbxmlBytes:
+ self.put(ord(byte))
+ self.bytesEnqueued += 1
+
+
+ logging.debug("Array byte count: %d, enqueued: %d" % (self.qsize(), self.bytesEnqueued))
+
+ """
+ Created to debug the dequeueing of bytes
+ """
+ def dequeueAndLog(self):
+ singleByte = self.get()
+ self.bytesDequeued += 1
+ logging.debug("Dequeued byte 0x{0:X} ({1} total)".format(singleByte, self.bytesDequeued))
+ return singleByte
+
+ """
+ Return true if the continuation bit is set in the byte
+ """
+ def checkContinuationBit(self, byteval):
+ continuationBitmask = 0x80
+ return (continuationBitmask & byteval) != 0
+
+ def dequeueMultibyteInt(self):
+ iReturn = 0
+ singleByte = 0xFF
+
+ while True:
+ iReturn <<= 7
+ if (self.qsize() == 0):
+ break
+ else:
+ singleByte = self.dequeueAndLog()
+ iReturn += int(singleByte & 0x7F)
+ if not self.checkContinuationBit(singleByte):
+ return iReturn
+
+ def dequeueString(self, length=None):
+ if ( length != None):
+ currentByte = 0x00
+ strReturn = ""
+ for i in range(0, length):
+ # TODO: Improve this handling. We are technically UTF-8, meaning
+ # that characters could be more than one byte long. This will fail if we have
+ # characters outside of the US-ASCII range
+ if ( self.qsize() == 0 ):
+ break
+ currentByte = self.dequeueAndLog()
+ strReturn += chr(currentByte)
+
+ else:
+ currentByte = 0x00
+ strReturn = ""
+ while True:
+ currentByte = self.dequeueAndLog()
+ if (currentByte != 0x00):
+ strReturn += chr(currentByte)
+ else:
+ break
+
+ return strReturn
+
diff --git a/libmproxy/contrib/wbxml/ASWBXMLCodePage.py b/libmproxy/contrib/wbxml/ASWBXMLCodePage.py
new file mode 100644
index 00000000..54b5d941
--- /dev/null
+++ b/libmproxy/contrib/wbxml/ASWBXMLCodePage.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: ASWBXMLCodePage.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+class ASWBXMLCodePage:
+ def __init__(self):
+ self.namespace = ""
+ self.xmlns = ""
+ self.tokenLookup = {}
+ self.tagLookup = {}
+
+ def addToken(self, token, tag):
+ self.tokenLookup[token] = tag
+ self.tagLookup[tag] = token
+
+ def getToken(self, tag):
+ if self.tagLookup.has_key(tag):
+ return self.tagLookup[tag]
+ return 0xFF
+
+ def getTag(self, token):
+ if self.tokenLookup.has_key(token):
+ return self.tokenLookup[token]
+ return None
+
+ def __repr__(self):
+ return str(self.tokenLookup) \ No newline at end of file
diff --git a/libmproxy/contrib/wbxml/GlobalTokens.py b/libmproxy/contrib/wbxml/GlobalTokens.py
new file mode 100644
index 00000000..8564397f
--- /dev/null
+++ b/libmproxy/contrib/wbxml/GlobalTokens.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: GlobalTokens.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+class GlobalTokens:
+ SWITCH_PAGE = 0x00
+ END = 0x01
+ ENTITY = 0x02
+ STR_I = 0x03
+ LITERAL = 0x04
+ EXT_I_0 = 0x40
+ EXT_I_1 = 0x41
+ EXT_I_2 = 0x42
+ PI = 0x43
+ LITERAL_C = 0x44
+ EXT_T_0 = 0x80
+ EXT_T_1 = 0x81
+ EXT_T_2 = 0x82
+ STR_T = 0x83
+ LITERAL_A = 0x84
+ EXT_0 = 0xC0
+ EXT_1 = 0xC1
+ EXT_2 = 0xC2
+ OPAQUE = 0xC3
+ LITERAL_AC = 0xC4 \ No newline at end of file
diff --git a/libmproxy/contrib/wbxml/InvalidDataException.py b/libmproxy/contrib/wbxml/InvalidDataException.py
new file mode 100644
index 00000000..ffc0a8cf
--- /dev/null
+++ b/libmproxy/contrib/wbxml/InvalidDataException.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+'''
+@author: David Shaw, david.shaw.aw@gmail.com
+
+Inspired by EAS Inspector for Fiddler
+https://easinspectorforfiddler.codeplex.com
+
+----- Apache License, Version 2.0 -----
+Filename: InvalidDataException.py
+Copyright 2014, David P. Shaw
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+'''
+class InvalidDataException(Exception):
+ pass \ No newline at end of file
diff --git a/libmproxy/contrib/wbxml/__init__.py b/libmproxy/contrib/wbxml/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/libmproxy/contrib/wbxml/__init__.py