def OnClick(event): global filename global netidenttree, textarea global dict_nodes if (len(netidenttree.selection()) == 0): return dict_node_id = netidenttree.item(netidenttree.selection(), "text") sig_dict = None for dict_node in dict_nodes: number = dict_node[0] if (number == dict_node_id): sig_dict = dict_node[1] break if (sig_dict == None): print("Error while retrieving data for selected network") return textarea.delete(1.0, END) id_string = sig_dict['Identifier'].firstChild.toxml() textarea.insert(END, "Network data\n") textarea.insert(END, "\n") #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime(timestamp_string, "%Y-%m-%dT%H:%M:%S") textarea.insert(END, "Network last seen in date: %s\n" % timestamp) # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) textarea.insert(END, "IP Address: %s\n" % ip) textarea.insert(END, "MAC Address: %s\n" % mac) else: textarea.insert(END, "Network identifier: %s\n" % id_string) # parse services dict services = plistutils.readArray(sig_dict['Services']) for service in services: textarea.insert(END, "\n") textarea.insert(END, "****** Service\n") service_dict = plistutils.readDict(service) textarea.insert( END, "Service ID: %s\n" % service_dict['ServiceID'].firstChild.toxml()) for key in service_dict.keys(): if (service_dict[key].nodeName != 'dict'): continue textarea.insert(END, "%s data\n" % key) single_service = plistutils.readDict(service_dict[key]) for element_key in single_service.keys(): element = single_service[element_key] if (element.nodeName == 'string'): textarea.insert( END, "- %s: %s\n" % (element_key, element.firstChild.toxml())) elif (element.nodeName == 'array'): textarea.insert(END, "- %s\n" % (element_key)) element_array = plistutils.readArray(element) for element_array_single in element_array: textarea.insert( END, " - %s\n" % (element_array_single.firstChild.toxml())) else: textarea.insert(END, "- %s: %s\n" % (element_key, element))
def main(mbdb, backup_path): global filename global historytree, textarea, historywindow global titlefootertext, urlfootertext filename = os.path.join(backup_path, mbdb.realFileName(filename="History.plist", domaintype="HomeDomain", path="Library/Safari")) if (not os.path.isfile(filename)): print("Invalid file name for Safari History database: %s"%filename) return # main window historywindow = Toplevel() historywindow.title('Safari History data') historywindow.focus_set() historywindow.grid_columnconfigure(0, weight=1) historywindow.grid_rowconfigure(1, weight=1) # header label contactstitle = Label(historywindow, text = "Safari History data from: " + filename, relief = RIDGE) contactstitle.grid(column = 0, row = 0, sticky="ew", padx=5, pady=5) # convert binary plist file into plain plist file historyxml = plistutils.readPlistToXml(filename) if (historyxml == None): print("Error while parsing Safari History Data") return # main dictionary (contains anything else) maindicts = historyxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read WebHistoryDates array of dicts (one dict for each bookmark) from plistutils import readDict, readArray outerDict = readDict(maindict) bookmarksArray = readArray(outerDict['WebHistoryDates']) bookmarks = [] # decode each bookmark dict for element in bookmarksArray: bookmark = {} elementDict = readDict(element) bookmark['title'] = "" if ('title' in elementDict.keys()): bookmark['title'] = elementDict['title'].firstChild.toxml() bookmark['url'] = "" if ('-' in elementDict.keys()): bookmark['url'] = elementDict['-'].firstChild.toxml() bookmark['date'] = "" if ('lastVisitedDate' in elementDict.keys()): bookmark['date'] = elementDict['lastVisitedDate'].firstChild.toxml() bookmarks.append(bookmark) # tree historytree = ttk.Treeview(historywindow, columns=("title", "url"), displaycolumns=("title", "url")) historytree.heading("#0", text="Date", anchor='w') historytree.heading("title", text="Title", anchor='w') historytree.heading("url", text="Url", anchor='w') historytree.column("#0", width=25) historytree.column("title", width=250) historytree.column("url", width=300) historytree.grid(column = 0, row = 1, sticky="ewns") # details box detailsbox = Frame(historywindow, bd=2, relief=RAISED); detailsbox.grid(column = 0, row = 2, sticky="ew", padx=5, pady=5) detailsbox.grid_columnconfigure(1, weight=1) titlefooterlabel = Label(detailsbox, text = 'Title:', relief = RIDGE, width=10) titlefooterlabel.grid(column = 0, row = 0, sticky="ew", padx=2, pady=2) titlefootertext = StringVar() titlefooter = Label(detailsbox, textvariable = titlefootertext, relief = RIDGE, anchor = 'w') titlefooter.grid(column = 1, row = 0, sticky="ew", padx=2, pady=2) titlefootertext.set("mille") urlfooterlabel = Label(detailsbox, text = 'URL:', relief = RIDGE, width=10) urlfooterlabel.grid(column = 0, row = 1, sticky="ew", padx=2, pady=2) urlfootertext = StringVar() urlfooter = Label(detailsbox, textvariable = urlfootertext, relief = RIDGE, anchor = 'w') urlfooter.grid(column = 1, row = 1, sticky="ew", padx=2, pady=2) urlfootertext.set("mille") # footer label footerlabel = StringVar() contactsfooter = Label(historywindow, textvariable = footerlabel, relief = RIDGE) contactsfooter.grid(column = 0, row = 3, sticky="ew", padx=5, pady=5) # destroy window when closed historywindow.protocol("WM_DELETE_WINDOW", historywindow.destroy) # footer statistics footerlabel.set("Found %s Safari history records"%(len(bookmarks))) # populating bookmarks tree for bookmark in bookmarks: timestamp = float(bookmark['date']) + 978307200 #JAN 1 1970 convtimestamp = datetime.fromtimestamp(int(timestamp)) historytree.insert( '', 'end', text = convtimestamp, values = ( bookmark['title'], bookmark['url'] ) ) historytree.bind("<ButtonRelease-1>", OnClick) historytree.bind("<Double-Button-1>", OnDoubleClick)
def main(cursor, backup_path): global filename global netidenttree, textarea, netidentwindow global dict_nodes filename = os.path.join( backup_path, plugins_utils.realFileName( cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(filename)): print("Invalid file name for network identification data: %s" % filename) return # main window netidentwindow = Toplevel() netidentwindow.title('Network Identification') netidentwindow.focus_set() netidentwindow.grid_columnconfigure(1, weight=1) netidentwindow.grid_rowconfigure(1, weight=1) # header label netidenttitle = Label(netidentwindow, text="Network Identification data from: %s (%s) " % (filename, "com.apple.network.identification.plist"), relief=RIDGE, width=100, height=3, wraplength=800, justify=LEFT) netidenttitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree netidenttree = ttk.Treeview( netidentwindow, columns=("id", "timestamp", "node"), displaycolumns=("id", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) netidenttree.heading("#0", text="", anchor='w') netidenttree.heading("id", text="ID", anchor='w') netidenttree.heading("timestamp", text="Time", anchor='w') netidenttree.column("#0", width=40) netidenttree.column("id", width=250) netidenttree.column("timestamp", width=150) netidenttree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(netidentwindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=2, row=1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(netidentwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = netidenttree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(netidentwindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() netidentfooter = Label(netidentwindow, textvariable=footerlabel, relief=RIDGE) netidentfooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed netidentwindow.protocol("WM_DELETE_WINDOW", netidentwindow.destroy) # convert binary plist file into plain plist file netidentxml = plistutils.readPlistToXml(filename) if (netidentxml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = netidentxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract Signatures array maindictelements = plistutils.readDict(maindict) try: signatures = maindictelements['Signatures'] except: print("No Signatures array found in main dict") return signatures_array = plistutils.readArray(signatures) # footer statistics footerlabel.set("Found %i identified networks." % (len(signatures_array))) id_number = 0 for signature in signatures_array: sig_dict = plistutils.readDict(signature) id_string = sig_dict['Identifier'].firstChild.toxml() #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime(timestamp_string, "%Y-%m-%dT%H:%M:%S") elem_id = "" # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) elem_id = "%s (%s)" % (ip, mac) else: elem_id = id_string netidenttree.insert('', 'end', text=id_number, values=(elem_id, timestamp, sig_dict)) dict_nodes.append([id_number, sig_dict]) id_number = id_number + 1 netidenttree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global netidenttree, textarea, netidentwindow global dict_nodes filename = os.path.join(backup_path, plugins_utils.realFileName(cursor, filename="com.apple.network.identification.plist", domaintype="SystemPreferencesDomain")) if (not os.path.isfile(filename)): print("Invalid file name for network identification data: %s"%filename) return # main window netidentwindow = Toplevel() netidentwindow.title('Network Identification') netidentwindow.focus_set() netidentwindow.grid_columnconfigure(1, weight=1) netidentwindow.grid_rowconfigure(1, weight=1) # header label netidenttitle = Label( netidentwindow, text = "Network Identification data from: %s (%s) "%(filename, "com.apple.network.identification.plist"), relief = RIDGE, width=100, height=3, wraplength=800, justify=LEFT ) netidenttitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree netidenttree = ttk.Treeview( netidentwindow, columns=("id", "timestamp", "node"), displaycolumns=("id", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l) ) netidenttree.heading("#0", text="", anchor='w') netidenttree.heading("id", text="ID", anchor='w') netidenttree.heading("timestamp", text="Time", anchor='w') netidenttree.column("#0", width=40) netidenttree.column("id", width=250) netidenttree.column("timestamp", width=150) netidenttree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text( netidentwindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l) ) textarea.grid(column = 2, row = 1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(netidentwindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = netidenttree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(netidentwindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() netidentfooter = Label(netidentwindow, textvariable = footerlabel, relief = RIDGE) netidentfooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed netidentwindow.protocol("WM_DELETE_WINDOW", netidentwindow.destroy) # convert binary plist file into plain plist file netidentxml = plistutils.readPlistToXml(filename) if (netidentxml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = netidentxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract Signatures array maindictelements = plistutils.readDict(maindict) try: signatures = maindictelements['Signatures'] except: print("No Signatures array found in main dict") return signatures_array = plistutils.readArray(signatures) # footer statistics footerlabel.set("Found %i identified networks."%(len(signatures_array))) id_number = 0 for signature in signatures_array: sig_dict = plistutils.readDict(signature) id_string = sig_dict['Identifier'].firstChild.toxml() #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime( timestamp_string, "%Y-%m-%dT%H:%M:%S" ) elem_id = "" # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) elem_id = "%s (%s)"%(ip, mac) else: elem_id = id_string netidenttree.insert('', 'end', text=id_number, values=(elem_id, timestamp, sig_dict)) dict_nodes.append([id_number, sig_dict]) id_number = id_number + 1 netidenttree.bind("<ButtonRelease-1>", OnClick)
def OnClick(event): global filename global netidenttree, textarea global dict_nodes if (len(netidenttree.selection()) == 0): return; dict_node_id = netidenttree.item(netidenttree.selection(), "text") sig_dict = None for dict_node in dict_nodes: number = dict_node[0] if (number == dict_node_id): sig_dict = dict_node[1] break if (sig_dict == None): print("Error while retrieving data for selected network") return textarea.delete(1.0, END) id_string = sig_dict['Identifier'].firstChild.toxml() textarea.insert(END, "Network data\n") textarea.insert(END, "\n") #2011-12-27T17:35:53.290510Z timestamp_string = sig_dict['Timestamp'].firstChild.toxml() if ("." in timestamp_string): timestamp_string = timestamp_string.split(".")[0] timestamp = datetime.datetime.strptime( timestamp_string, "%Y-%m-%dT%H:%M:%S" ) textarea.insert(END, "Network last seen in date: %s\n"%timestamp) # parse identification for IPv4 routers if (id_string.startswith('IPv4')): [ip, mac] = parseipv4(id_string) textarea.insert(END, "IP Address: %s\n"%ip) textarea.insert(END, "MAC Address: %s\n"%mac) else: textarea.insert(END, "Network identifier: %s\n"%id_string) # parse services dict services = plistutils.readArray(sig_dict['Services']) for service in services: textarea.insert(END, "\n") textarea.insert(END, "****** Service\n") service_dict = plistutils.readDict(service) textarea.insert(END, "Service ID: %s\n"%service_dict['ServiceID'].firstChild.toxml()) for key in service_dict.keys(): if (service_dict[key].nodeName != 'dict'): continue textarea.insert(END, "%s data\n"%key) single_service = plistutils.readDict(service_dict[key]) for element_key in single_service.keys(): element = single_service[element_key] if (element.nodeName == 'string'): textarea.insert(END, "- %s: %s\n"%(element_key, element.firstChild.toxml())) elif (element.nodeName == 'array'): textarea.insert(END, "- %s\n"%(element_key)) element_array = plistutils.readArray(element) for element_array_single in element_array: textarea.insert(END, " - %s\n"%(element_array_single.firstChild.toxml())) else: textarea.insert(END, "- %s: %s\n"%(element_key, element))
def OnClick(event): global filename global safstatetree, textarea global dict_nodes if (len(safstatetree.selection()) == 0): return dict_node_id = safstatetree.item(safstatetree.selection(), "text") sig_dict = None for dict_node in dict_nodes: number = dict_node[0] if (number == dict_node_id): sig_dict = dict_node[1] break if (sig_dict == None): print("Error while retrieving data for selected element") return textarea.delete(1.0, END) textarea.insert(END, "Safari tab data\n") textarea.insert(END, "\n") try: title_string = sig_dict['SafariStateDocumentTitle'].firstChild.toxml() except: title_string = "" textarea.insert(END, "Page title: %s\n" % title_string) url_string = sig_dict['SafariStateDocumentURL'].firstChild.toxml() textarea.insert(END, "Page url: %s\n" % url_string) timestamp_val = float( sig_dict['SafariStateDocumentLastViewedTime'].firstChild.toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") textarea.insert(END, "Last viewed in date: %s\n" % timestamp) # parse back forward list backforwardlist_info = plistutils.readDict( sig_dict['SafariStateDocumentBackForwardList']) textarea.insert(END, "\n") textarea.insert(END, "Back/forward list data\n") textarea.insert( END, "Capacity: %s\n" % (backforwardlist_info['capacity'].firstChild.toxml())) current = int(backforwardlist_info['current'].firstChild.toxml()) textarea.insert(END, "Current: %i\n" % (current)) backforwardlist = plistutils.readArray(backforwardlist_info['entries']) actual = 0 for backforward in backforwardlist: actual_string = "" if (actual == current): actual_string = "(CURRENT)" textarea.insert(END, "\n") textarea.insert( END, "****** Back/Forward list element %i %s\n" % (actual, actual_string)) backforward_dict = plistutils.readDict(backforward) textarea.insert( END, "Title: %s\n" % (backforward_dict['title'].firstChild.toxml())) textarea.insert( END, "URL: %s\n" % (backforward_dict['-'].firstChild.toxml())) actual = actual + 1
def main(cursor, backup_path): global filename global safstatetree, textarea, safstatewindow global dict_nodes filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="SuspendState.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari state data: %s" % filename) return # main window safstatewindow = Toplevel() safstatewindow.title('Safari State') safstatewindow.focus_set() safstatewindow.grid_columnconfigure(1, weight=1) safstatewindow.grid_rowconfigure(1, weight=1) # header label safstatetitle = Label(safstatewindow, text="Safari State data from: %s (%s) " % (filename, "SuspendState.plist"), relief=RIDGE, width=100, height=3, wraplength=800, justify=LEFT) safstatetitle.grid(column=0, row=0, sticky="ew", columnspan=4, padx=5, pady=5) # tree safstatetree = ttk.Treeview( safstatewindow, columns=("active", "title", "timestamp"), displaycolumns=("active", "title", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l)) safstatetree.heading("#0", text="", anchor='w') safstatetree.heading("active", text="A", anchor='w') safstatetree.heading("title", text="Title", anchor='w') safstatetree.heading("timestamp", text="Timestamp", anchor='w') safstatetree.column("#0", width=30) safstatetree.column("active", width=20) safstatetree.column("title", width=250) safstatetree.column("timestamp", width=160) safstatetree.grid(column=0, row=1, sticky="ns") # textarea textarea = Text(safstatewindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l)) textarea.grid(column=2, row=1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(safstatewindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = safstatetree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(safstatewindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() safstatefooter = Label(safstatewindow, textvariable=footerlabel, relief=RIDGE) safstatefooter.grid(column=0, row=2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed safstatewindow.protocol("WM_DELETE_WINDOW", safstatewindow.destroy) # convert binary plist file into plain plist file safstatexml = plistutils.readPlistToXml(filename) if (safstatexml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = safstatexml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract SafariStateDocuments array maindictelements = plistutils.readDict(maindict) try: safstatedocs = maindictelements['SafariStateDocuments'] except: print("No SafariStateDocuments array found in main dict") return active_tab = int( maindictelements['SafariStateActiveDocumentIndex'].firstChild.toxml()) safstatedocs_array = plistutils.readArray(safstatedocs) # footer statistics footerlabel.set("Found %i open tabs." % (len(safstatedocs_array))) id_number = 0 for safstatedoc in safstatedocs_array: safstatedoc_dict = plistutils.readDict(safstatedoc) try: title = safstatedoc_dict[ 'SafariStateDocumentTitle'].firstChild.toxml() except: title = "" timestamp_val = float( safstatedoc_dict['SafariStateDocumentLastViewedTime'].firstChild. toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") active_status = "" if (active_tab == id_number): active_status = "*" safstatetree.insert('', 'end', text=id_number, values=(active_status, title, timestamp)) dict_nodes.append([id_number, safstatedoc_dict]) id_number = id_number + 1 safstatetree.bind("<ButtonRelease-1>", OnClick)
def main(cursor, backup_path): global filename global historytree, textarea, historywindow global titlefootertext, urlfootertext filename = os.path.join( backup_path, plugins_utils.realFileName(cursor, filename="History.plist", domaintype="HomeDomain", path="Library/Safari")) if (not os.path.isfile(filename)): print("Invalid file name for Safari History database: %s" % filename) return # main window historywindow = Toplevel() historywindow.title('Safari History data') historywindow.focus_set() historywindow.grid_columnconfigure(0, weight=1) historywindow.grid_rowconfigure(1, weight=1) # header label contactstitle = Label(historywindow, text="Safari History data from: " + filename, relief=RIDGE) contactstitle.grid(column=0, row=0, sticky="ew", padx=5, pady=5) # convert binary plist file into plain plist file historyxml = plistutils.readPlistToXml(filename) if (historyxml == None): print("Error while parsing Safari History Data") return # main dictionary (contains anything else) maindicts = historyxml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # read WebHistoryDates array of dicts (one dict for each bookmark) from plistutils import readDict, readArray outerDict = readDict(maindict) bookmarksArray = readArray(outerDict['WebHistoryDates']) bookmarks = [] # decode each bookmark dict for element in bookmarksArray: bookmark = {} elementDict = readDict(element) bookmark['title'] = "" if ('title' in elementDict.keys()): bookmark['title'] = elementDict['title'].firstChild.toxml() bookmark['url'] = "" if ('-' in elementDict.keys()): bookmark['url'] = elementDict['-'].firstChild.toxml() bookmark['date'] = "" if ('lastVisitedDate' in elementDict.keys()): bookmark['date'] = elementDict['lastVisitedDate'].firstChild.toxml( ) bookmarks.append(bookmark) # tree historytree = ttk.Treeview(historywindow, columns=("title", "url"), displaycolumns=("title", "url")) historytree.heading("#0", text="Date", anchor='w') historytree.heading("title", text="Title", anchor='w') historytree.heading("url", text="Url", anchor='w') historytree.column("#0", width=25) historytree.column("title", width=250) historytree.column("url", width=300) historytree.grid(column=0, row=1, sticky="ewns") # details box detailsbox = Frame(historywindow, bd=2, relief=RAISED) detailsbox.grid(column=0, row=2, sticky="ew", padx=5, pady=5) detailsbox.grid_columnconfigure(1, weight=1) titlefooterlabel = Label(detailsbox, text='Title:', relief=RIDGE, width=10) titlefooterlabel.grid(column=0, row=0, sticky="ew", padx=2, pady=2) titlefootertext = StringVar() titlefooter = Label(detailsbox, textvariable=titlefootertext, relief=RIDGE, anchor='w') titlefooter.grid(column=1, row=0, sticky="ew", padx=2, pady=2) titlefootertext.set("mille") urlfooterlabel = Label(detailsbox, text='URL:', relief=RIDGE, width=10) urlfooterlabel.grid(column=0, row=1, sticky="ew", padx=2, pady=2) urlfootertext = StringVar() urlfooter = Label(detailsbox, textvariable=urlfootertext, relief=RIDGE, anchor='w') urlfooter.grid(column=1, row=1, sticky="ew", padx=2, pady=2) urlfootertext.set("mille") # footer label footerlabel = StringVar() contactsfooter = Label(historywindow, textvariable=footerlabel, relief=RIDGE) contactsfooter.grid(column=0, row=3, sticky="ew", padx=5, pady=5) # destroy window when closed historywindow.protocol("WM_DELETE_WINDOW", historywindow.destroy) # footer statistics footerlabel.set("Found %s Safari history records" % (len(bookmarks))) # populating bookmarks tree for bookmark in bookmarks: timestamp = float(bookmark['date']) + 978307200 #JAN 1 1970 convtimestamp = datetime.fromtimestamp(int(timestamp)) historytree.insert('', 'end', text=convtimestamp, values=(bookmark['title'], bookmark['url'])) historytree.bind("<ButtonRelease-1>", OnClick) historytree.bind("<Double-Button-1>", OnDoubleClick)
def OnClick(event): global filename global safstatetree, textarea global dict_nodes if (len(safstatetree.selection()) == 0): return; dict_node_id = safstatetree.item(safstatetree.selection(), "text") sig_dict = None for dict_node in dict_nodes: number = dict_node[0] if (number == dict_node_id): sig_dict = dict_node[1] break if (sig_dict == None): print("Error while retrieving data for selected element") return textarea.delete(1.0, END) textarea.insert(END, "Safari tab data\n") textarea.insert(END, "\n") try: title_string = sig_dict['SafariStateDocumentTitle'].firstChild.toxml() except: title_string = "" textarea.insert(END, "Page title: %s\n"%title_string) url_string = sig_dict['SafariStateDocumentURL'].firstChild.toxml() textarea.insert(END, "Page url: %s\n"%url_string) timestamp_val = float(sig_dict['SafariStateDocumentLastViewedTime'].firstChild.toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") textarea.insert(END, "Last viewed in date: %s\n"%timestamp) # parse back forward list backforwardlist_info = plistutils.readDict(sig_dict['SafariStateDocumentBackForwardList']) textarea.insert(END, "\n") textarea.insert(END, "Back/forward list data\n") textarea.insert(END, "Capacity: %s\n"%(backforwardlist_info['capacity'].firstChild.toxml())) current = int(backforwardlist_info['current'].firstChild.toxml()) textarea.insert(END, "Current: %i\n"%(current)) backforwardlist = plistutils.readArray(backforwardlist_info['entries']) actual = 0 for backforward in backforwardlist: actual_string = "" if (actual == current): actual_string = "(CURRENT)" textarea.insert(END, "\n") textarea.insert(END, "****** Back/Forward list element %i %s\n"%(actual, actual_string)) backforward_dict = plistutils.readDict(backforward) textarea.insert(END, "Title: %s\n"%(backforward_dict['title'].firstChild.toxml())) textarea.insert(END, "URL: %s\n"%(backforward_dict['-'].firstChild.toxml())) actual = actual + 1
def main(mbdb, backup_path): global filename global safstatetree, textarea, safstatewindow global dict_nodes filename = os.path.join(backup_path, mbdb.realFileName(filename="SuspendState.plist", domaintype="HomeDomain")) if (not os.path.isfile(filename)): print("Invalid file name for Safari state data: %s"%filename) return # main window safstatewindow = Toplevel() safstatewindow.title('Safari State') safstatewindow.focus_set() safstatewindow.grid_columnconfigure(1, weight=1) safstatewindow.grid_rowconfigure(1, weight=1) # header label safstatetitle = Label( safstatewindow, text = "Safari State data from: %s (%s) "%(filename, "SuspendState.plist"), relief = RIDGE, width=100, height=3, wraplength=800, justify=LEFT ) safstatetitle.grid(column = 0, row = 0, sticky="ew", columnspan=4, padx=5, pady=5) # tree safstatetree = ttk.Treeview( safstatewindow, columns=("active", "title", "timestamp"), displaycolumns=("active", "title", "timestamp"), yscrollcommand=lambda f, l: autoscroll(mvsb, f, l) ) safstatetree.heading("#0", text="", anchor='w') safstatetree.heading("active", text="A", anchor='w') safstatetree.heading("title", text="Title", anchor='w') safstatetree.heading("timestamp", text="Timestamp", anchor='w') safstatetree.column("#0", width=30) safstatetree.column("active", width=20) safstatetree.column("title", width=250) safstatetree.column("timestamp", width=160) safstatetree.grid(column = 0, row = 1, sticky="ns") # textarea textarea = Text( safstatewindow, bd=2, relief=SUNKEN, yscrollcommand=lambda f, l: autoscroll(tvsb, f, l) ) textarea.grid(column = 2, row = 1, sticky="nsew") # scrollbars for tree mvsb = ttk.Scrollbar(safstatewindow, orient="vertical") mvsb.grid(column=1, row=1, sticky='ns') mvsb['command'] = safstatetree.yview # scrollbars for main textarea tvsb = ttk.Scrollbar(safstatewindow, orient="vertical") tvsb.grid(column=3, row=1, sticky='ns') tvsb['command'] = textarea.yview # footer label footerlabel = StringVar() safstatefooter = Label(safstatewindow, textvariable = footerlabel, relief = RIDGE) safstatefooter.grid(column = 0, row = 2, sticky="ew", columnspan=4, padx=5, pady=5) # destroy window when closed safstatewindow.protocol("WM_DELETE_WINDOW", safstatewindow.destroy) # convert binary plist file into plain plist file safstatexml = plistutils.readPlistToXml(filename) if (safstatexml == None): print("Error while parsing binary plist data") return # main dictionary (contains anything else) maindicts = safstatexml.getElementsByTagName('dict') if (len(maindicts) <= 0): print("no main dict found in file") return maindict = maindicts[0] # extract SafariStateDocuments array maindictelements = plistutils.readDict(maindict) try: safstatedocs = maindictelements['SafariStateDocuments'] except: print("No SafariStateDocuments array found in main dict") return active_tab = int(maindictelements['SafariStateActiveDocumentIndex'].firstChild.toxml()) safstatedocs_array = plistutils.readArray(safstatedocs) # footer statistics footerlabel.set("Found %i open tabs."%(len(safstatedocs_array))) id_number = 0 for safstatedoc in safstatedocs_array: safstatedoc_dict = plistutils.readDict(safstatedoc) try: title = safstatedoc_dict['SafariStateDocumentTitle'].firstChild.toxml() except: title = "" timestamp_val = float(safstatedoc_dict['SafariStateDocumentLastViewedTime'].firstChild.toxml()) timestamp_val = timestamp_val + 978307200 #JAN 1 1970 timestamp = datetime.datetime.fromtimestamp(timestamp_val) timestamp = timestamp.strftime("%Y-%m-%d %H:%M") active_status = "" if (active_tab == id_number): active_status = "*" safstatetree.insert('', 'end', text=id_number, values=(active_status, title, timestamp)) dict_nodes.append([id_number, safstatedoc_dict]) id_number = id_number + 1 safstatetree.bind("<ButtonRelease-1>", OnClick)