~mozillateam/firefox/firefox-3.6.head

194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
1
'''firefox apport hook draft
2
521 by Micah Gersten
* Rename apport hook to firefox.py (unversioned)
3
/usr/share/apport/package-hooks/firefox.py
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
4
5
Appends to apport's firefox default report: the files pluginreg.dat and
6
profiles.ini, and also a summary of all the extensions loaded on each firefox
7
profile (the summary is the extension's name, it's version, and the id)
8
obtained by parsing each extension's install.rdf file.
9
10
Copyright (c) 2007: Hilario J. Montoliu <hmontoliu@gmail.com>
11
12
This program is free software; you can redistribute it and/or modify it
13
under the terms of the GNU General Public License as published by the
14
Free Software Foundation; either version 2 of the License, or (at your
15
option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
16
the full text of the license.
17
'''
18
19
import os
20
import ConfigParser
21
import cStringIO
22
from xml.dom import minidom
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
23
import re
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
24
25
def extensions_ini_parser(extensions_ini_file):
26
    '''parses profile's extensions.ini file and returns a tuple:
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
27
    ((gre extensions, app extensions, local extensions), (gre themes, app
28
    themes, local themes))'''
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
29
    parser = ConfigParser.ConfigParser()
30
    parser.read(extensions_ini_file) 
31
    ext_ini_d = {}
32
    for section in parser.sections():
247.1.21 by Alexander Sack
* Fix apport hook to properly detect global gre extensions
33
        section_gre, section_app, section_local, my_ext = [], [], [], ''
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
34
        for extension in parser.options(section):
35
            my_ext = parser.get(section, extension)
247.1.21 by Alexander Sack
* Fix apport hook to properly detect global gre extensions
36
            if '/usr/lib/xulrunner' in my_ext:
117.1.35 by Alexander Sack
* fix extension and theme reporting in apport hook. we now list gre,
37
                section_gre.append((my_ext))
38
            elif '/usr/lib/firefox' in my_ext:
39
                section_app.append((my_ext))
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
40
            else:
41
                section_local.append((my_ext))
117.1.35 by Alexander Sack
* fix extension and theme reporting in apport hook. we now list gre,
42
        ext_ini_d[section] = (section_gre, section_app, section_local)
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
43
    return (ext_ini_d['ExtensionDirs'], ext_ini_d['ThemeDirs'])
44
45
def install_ini_parser(extension_path):
46
    '''parses each extension's install.rdf and returns string:
47
    extension name, its version and the id.'''
48
    rdf_file = os.path.join(extension_path, 'install.rdf')
229 by Fabien Tassin
* Fix the apport hook to survive when a profile points to an extension
49
    if not os.path.exists(extension_path):
50
        return '''  %s does not exist (old profile?)''' % extension_path
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
51
    refs_dict = {'em:version': '', 'em:id': '', 'em:name': ''}
52
    parse_err = '%s (Not Parsed)\n' % extension_path 
53
    dom_doc = minidom.parse(rdf_file)
54
    for key in refs_dict.keys():
55
        this_key = ''
56
        try:
57
            document_ref = dom_doc.getElementsByTagName('RDF:Description')[0].attributes
58
            this_key = document_ref[key].value
59
        except:
60
            try:
61
                document_ref = dom_doc.getElementsByTagName('Description')[0].attributes
62
                this_key = document_ref[key].value
63
            except: 
64
                try:
65
                    this_key = dom_doc.getElementsByTagName(key)[0].childNodes[0].data
66
                except:
67
                    return parse_err
68
        try: # avoid problems with encodings.
69
            print >> cStringIO.StringIO(), this_key
70
            refs_dict[key] = this_key            
71
        except UnicodeEncodeError:    
72
            refs_dict[key] = repr(this_key)
73
    return '''%(em:name)s (version: %(em:version)s) -\tid: %(em:id)s''' % refs_dict
74
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
75
def extension_summary_helper(extension_list, section_name, profile_path, alt_output = 1):
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
76
    '''does some output proccessing for extensionSummary'''
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
77
    summary = ''
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
78
    if len(extension_list) > 0:
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
79
        summary += '''  %s:\n''' % section_name
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
80
        for extension in extension_list:
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
81
            summary += '''    %s\n''' % re.sub(profile_path, '/<hidden_local_profile>', install_ini_parser(extension))
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
82
    else:
83
        if alt_output == 1: # if 0, don't output anything
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
84
            summary += '''  No %s in this Profile.\n''' % section_name 
85
    summary += '''\n'''
86
    return summary
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
87
465 by Jamie Strandboge
[ Jamie Strandboge <jamie@ubuntu.com> ]
88
def recent_kernlog(pattern):
89
    '''Extract recent messages from kern.log or message which match a regex.
90
       pattern should be a "re" object.  '''
91
    lines = ''
92
    if os.path.exists('/var/log/kern.log'):
93
        file = '/var/log/kern.log'
94
    elif os.path.exists('/var/log/messages'):
95
        file = '/var/log/messages'
96
    else:
97
        return lines
98
99
    for line in open(file):
100
        if pattern.search(line):
101
            lines += line
102
    return lines
103
104
def recent_auditlog(pattern):
105
    '''Extract recent messages from kern.log or message which match a regex.
106
       pattern should be a "re" object.  '''
107
    lines = ''
108
    if os.path.exists('/var/log/audit/audit.log'):
109
        file = '/var/log/audit/audit.log'
110
    else:
111
        return lines
112
113
    for line in open(file):
114
        if pattern.search(line):
115
            lines += line
116
    return lines
117
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
118
def add_info(report):
522 by Micah Gersten
* Update apport hook to report on non-distro package and tag PPA
119
    if not apport.packaging.is_distro_package(report['Package'].split()[0]):
120
        report['ThirdParty'] = 'True'
635 by Micah Gersten
* Fix apport hook so PPA crashes/reports go to the Ubuntu Mozilla PPA bugs
121
        report['CrashDB'] = 'ubuntu-mozilla-ppa-bugs'
522 by Micah Gersten
* Update apport hook to report on non-distro package and tag PPA
122
123
    packages = ['firefox',
124
                'firefox-gnome-support',
125
                'firefox-branding',
126
		'abroswer',
127
		'abrowser-branding']
128
129
    versions = ''
130
    for package in packages:
131
        try:
132
            version = packaging.get_version(package)
133
        except ValueError:
134
            version = 'N/A'
135
        if version is None:
136
            version = 'N/A'
137
        versions += '%s %s\n' % (package, version)
138
    report['FirefoxPackages'] = versions
139
140
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
141
    '''adds hooked info into the apport report.'''
521 by Micah Gersten
* Rename apport hook to firefox.py (unversioned)
142
    config_dir = os.path.join(os.environ['HOME'], '.mozilla', 'firefox')
444 by Alexander Sack
* fix LP: #422365 - apport hook fails because profiles_d is not initialized
143
    profiles_d = {}
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
144
    # append profiles.ini file & parse it:
145
    profiles_ini = os.path.join(config_dir,'profiles.ini') 
146
    if os.path.exists(profiles_ini):
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
147
	profiles_ini_contents = ""
148
	for line in open(profiles_ini).readlines():
149
	    if not 'Path=' in line:
150
		profiles_ini_contents += line
151
	pbuffer = cStringIO.StringIO()
152
	print >> pbuffer, profiles_ini_contents
153
	pbuffer.seek(0)
154
        report['profiles.ini'] = pbuffer.read() 
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
155
        # parse profiles.ini: 
156
        profile_parser = ConfigParser.ConfigParser()
157
        profile_parser.read(profiles_ini)
158
        for section in profile_parser.sections():
159
            if profile_parser.has_option(section, 'Name') and profile_parser.has_option(section, 'Path'):
160
                if profile_parser.has_option(section, 'Default'):
161
                    is_default = profile_parser.get(section, 'Default')
162
                else:
163
                    is_default = 0
164
                profiles_d[profile_parser.get(section, 'Name')] = (os.path.join(config_dir, profile_parser.get(section, 'Path')), is_default)
165
    
166
    # summarize the extensions loaded on each profile (either global and local):
404.1.1 by H. Montoliu
* fix LP: #361052 - firefox apport hook fails to retrieve pluginreg.dat file
167
    # also append the pluginreg.dat file of the default profile (maybe in a
168
    # future append each profile's pluginreg.dat file)
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
169
    extensions_dict, themes_dict, extension_summary = {}, {}, ''
170
    for profile_name in profiles_d.keys():
538 by Micah Gersten
[ Kees Cook <kees@ubuntu.com> ]
171
        profile_name_apport = "".join(x for x in profile_name if x.isalnum())
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
172
        profile_path, is_default = profiles_d[profile_name]
173
        extensions_ini = os.path.join(profile_path, 'extensions.ini')
404.1.1 by H. Montoliu
* fix LP: #361052 - firefox apport hook fails to retrieve pluginreg.dat file
174
        pluginreg_dat = os.path.join(profile_path, 'pluginreg.dat')
175
        if os.path.exists(pluginreg_dat):
176
            if is_default == '1':
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
177
                report['default_profile_pluginreg.dat'] = re.sub(profile_path, '/<hidden_local_profile>', open(pluginreg_dat).read())
404.1.1 by H. Montoliu
* fix LP: #361052 - firefox apport hook fails to retrieve pluginreg.dat file
178
            else:
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
179
                report['profile_%s_pluginreg.dat' % profile_name_apport] = re.sub(profile_path, '/<hidden_local_profile>', open(pluginreg_dat).read())
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
180
        if os.path.exists(extensions_ini):
181
            # attach each profile's extensions.ini too (not enabled).
182
            #report['extensions.ini (profile: %s)' % profile_name ] = open(extensions_ini).read()
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
183
            (extensions_dict['gre_extensions'], extensions_dict['app_extensions'], extensions_dict['local_extensions']), \
117.1.35 by Alexander Sack
* fix extension and theme reporting in apport hook. we now list gre,
184
            (themes_dict['gre_theme'], themes_dict['app_theme'], themes_dict['local_theme']) = extensions_ini_parser(extensions_ini)
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
185
            if is_default == '1': 
186
                is_default_str = ''' (The Default):'''
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
187
            else: is_default_str = ''':'''
188
            extension_summary += '''Profile "%s"%s\n\n''' % (profile_name, is_default_str)
647 by Chris Coulson
* Fix LP: #612185 - Apport leaks the secret name of the Firefox
189
            extension_summary += extension_summary_helper(extensions_dict['gre_extensions'], 'GRE Extensions', profile_path)
190
            extension_summary += extension_summary_helper(extensions_dict['app_extensions'], 'Application Extensions', profile_path)
191
            extension_summary += extension_summary_helper(extensions_dict['local_extensions'], 'Local Extensions', profile_path)
192
            extension_summary += extension_summary_helper(themes_dict['gre_theme'], 'GRE Theme', profile_path, 0)
193
            extension_summary += extension_summary_helper(themes_dict['app_theme'], 'Application Theme', profile_path, 0)
194
            extension_summary += extension_summary_helper(themes_dict['local_theme'], 'Local Theme', profile_path, 0)
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
195
        wbuffer = cStringIO.StringIO() # it's needed for propper apport attachments
196
        print >> wbuffer, extension_summary
197
        wbuffer.seek(0)
198
    report['ExtensionSummary'] = wbuffer.read()
465 by Jamie Strandboge
[ Jamie Strandboge <jamie@ubuntu.com> ]
199
200
    # Get apparmor stuff if the profile isn't disabled. copied from
201
    # source_apparmor.py until apport runs hooks via attach_related_packages
202
    apparmor_disable_dir = "/etc/apparmor.d/disable"
203
    add_apparmor = True
204
    if os.path.isdir(apparmor_disable_dir):
205
        for f in os.listdir(apparmor_disable_dir):
206
            if f.startswith("usr.bin.firefox"):
207
                add_apparmor = False
208
                break
209
    if add_apparmor:
210
        attach_related_packages(report, ['apparmor', 'libapparmor1',
211
            'libapparmor-perl', 'apparmor-utils', 'auditd', 'libaudit0'])
212
213
        attach_file(report, '/proc/version_signature', 'ProcVersionSignature')
214
        attach_file(report, '/proc/cmdline', 'ProcCmdline')
215
216
        sec_re = re.compile('audit\(|apparmor|selinux|security', re.IGNORECASE)
217
        report['KernLog'] = recent_kernlog(sec_re)
218
219
        if os.path.exists("/var/log/audit"):
220
            # this needs to be run as root
221
            report['AuditLog'] = recent_auditlog(sec_re)
222
194 by asac
* reuse apport hook from firefox 2 package initially developed by Hilario J.
223
    # debug (comment on production)
224
    # return report
225
226
#### debug ####
227
# (uncomment the 'return report' at add_report())
228
if __name__ == "__main__":
229
    D = {}  
404.1.2 by H. Montoliu
* update debian/apport/firefox-3.0.py - removed unused code and minor refactoring.
230
    REPORT = add_info(D)
231
    for KEY in REPORT.keys(): 
232
        print '''-------------------%s: ------------------\n''' % KEY, REPORT[KEY]