Added accelerator for Download button.
[zeroinstall.git] / trust_box.py
blobfeb15d2b61a09407c4da0debc340bf30aeb0d247
1 import gtk
2 from zeroinstall.injector.model import SafeException
3 from zeroinstall.injector import gpg, trust
4 from zeroinstall.injector.iface_cache import iface_cache
6 import gui
7 import dialog, help_box
9 def fingerprint(sig):
10 try:
11 return sig.fingerprint
12 except:
13 # Work around a bug in injector-0.9
14 return sig.status[sig.FINGERPRINT]
16 def pretty_fp(fp):
17 s = fp[0:4]
18 for x in range(4, len(fp), 4):
19 s += ' ' + fp[x:x + 4]
20 return s
22 class TrustBox(dialog.Dialog):
23 interface = None
24 sigs = None
25 iface_xml = None
27 def __init__(self, interface, sigs, iface_xml):
28 dialog.Dialog.__init__(self)
29 self.connect('destroy', lambda a: _pop_queue())
31 def left(text):
32 label = gtk.Label(text)
33 label.set_alignment(0, 0.5)
34 label.set_selectable(True)
35 return label
37 self.interface = interface
38 self.sigs = sigs
39 self.iface_xml = iface_xml
41 self.set_title('Confirm trust')
43 vbox = gtk.VBox(False, 4)
44 vbox.set_border_width(4)
45 self.vbox.pack_start(vbox, True, True, 0)
47 label = left('Checking: ' + interface.uri + '\n\n'
48 'Please confirm that you trust '
49 'these keys to sign software updates:')
50 vbox.pack_start(label, False, True, 0)
52 notebook = gtk.Notebook()
53 vbox.pack_start(notebook, True, True, 0)
55 self.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
56 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
57 self.add_button(gtk.STOCK_ADD, gtk.RESPONSE_OK)
58 self.set_default_response(gtk.RESPONSE_OK)
60 valid_sigs = [s for s in sigs if isinstance(s, gpg.ValidSig)]
61 if not valid_sigs:
62 raise SafeException('No valid signatures found')
64 trust = {} # Sig -> CheckButton
65 def ok_sensitive():
66 trust_any = False
67 for toggle in trust.values():
68 if toggle.get_active():
69 trust_any = True
70 break
71 self.set_response_sensitive(gtk.RESPONSE_OK, trust_any)
72 for sig in sigs:
73 if hasattr(sig, 'get_details'):
74 name = '<unknown>'
75 details = sig.get_details()
76 for item in details:
77 if item[0] in ('pub', 'uid') and \
78 len(item) > 9:
79 name = item[9]
80 break
81 else:
82 name = None
83 page = gtk.VBox(False, 4)
84 page.set_border_width(8)
85 page.pack_start(left('Fingerprint: ' + pretty_fp(fingerprint(sig))), False, True, 0)
86 if name is not None:
87 page.pack_start(left('Claimed identity: ' + name), False, True, 0)
89 frame = gtk.Frame('Unreliable hints database says')
90 frame.set_border_width(4)
91 hint = left(hints.get(fingerprint(sig), 'Warning: Nothing known about this key!'))
92 hint.set_line_wrap(True)
93 hint.set_padding(4, 4)
94 frame.add(hint)
95 page.pack_start(frame, True, True, 0)
97 trust[sig] = gtk.CheckButton('Trust this key')
98 page.pack_start(trust[sig], False, True, 0)
99 trust[sig].connect('toggled', lambda t: ok_sensitive())
101 notebook.append_page(page, gtk.Label(name or 'Signature'))
103 ok_sensitive()
104 self.vbox.show_all()
106 def response(box, resp):
107 if resp == gtk.RESPONSE_HELP:
108 trust_help.display()
109 return
110 if resp == gtk.RESPONSE_OK:
111 self.trust_keys([sig for sig in trust if trust[sig].get_active()])
112 self.destroy()
113 self.connect('response', response)
115 self.present()
117 def trust_keys(self, sigs):
118 try:
119 for sig in sigs:
120 trust.trust_db.trust_key(fingerprint(sig))
122 if not iface_cache.update_interface_if_trusted(self.interface, self.sigs,
123 self.iface_xml):
124 raise Exception('Bug: still not trusted!!')
125 except Exception, ex:
126 dialog.alert(None, ex)
128 _queue = []
129 def _pop_queue():
130 if _queue:
131 a = _queue.pop()
132 a.show()
134 def confirm_trust(interface, sigs, iface_xml):
135 _queue.append(TrustBox(interface, sigs, iface_xml))
136 if len(_queue) == 1:
137 _pop_queue()
139 trust_help = help_box.HelpBox("Trust Help",
140 ('Overview', """
141 When you run a program, it typically has access to all your files and can generally do \
142 anything that you're allowed to do (delete files, send emails, etc). So it's important \
143 to make sure that you don't run anything malicious."""),
145 ('Digital signatures', """
146 Each software author creates a 'key-pair'; a 'public key' and a 'private key'. Without going \
147 into the maths, only something encrypted with the private key will decrypt with the public key.
149 So, when a programmer releases some software, they encrypt it with their private key (which no-one \
150 else has). When you download it, the injector checks that it decrypts using their public key, thus \
151 proving that it came from them and hasn't been tampered with."""),
153 ('Trust', """
154 After the injector has checked that the software hasn't been modified since it was signed with \
155 the private key, you still have the following problems:
157 1. Does the public key you have really belong to the author?
158 2. Even if the software really did come from that person, do you trust them?"""),
160 ('Key fingerprints', """
161 To confirm (1), you should compare the public key you have with the genuine one. To make this \
162 easier, the injector displays a 'fingerprint' for the key. Look in mailing list postings or some \
163 other source to check that the fingerprint is right (a different key will have a different \
164 fingerprint).
166 You're trying to protect against the situation where an attacker breaks into a web site \
167 and puts up malicious software, signed with the attacker's private key, and puts up the \
168 attacker's public key too. If you've downloaded this software before, you \
169 should be suspicious that you're being asked to confirm another key!"""),
171 ('Reputation', """
172 In general, most problems seem to come from malicous and otherwise-unknown people \
173 replacing software with modified versions, or creating new programs intended only to \
174 cause damage. So, check your programs are signed by a key with a good reputation!"""))
176 hints = {
177 '1DC295D11A3F910DA49D3839AA1A7812B40B0B6E' :
178 'Ken Hayber has been writing ROX applications since 2003. This key '
179 'was announced on the rox-users list on 5 Jun 2005.',
181 '4338D5420E0BAEB6B2E73530B66A4F24AB8B4B65' :
182 'Thomas Formella is experimenting with packaging programs for 0launch. This key '
183 'was announced on 11 Sep 2005 on the zero-install mailing list.',
185 '92429807C9853C0744A68B9AAE07828059A53CC1' :
186 'Thomas Leonard created Zero Install and ROX. This key is normally trusted by default.',
188 '0597A2AFB6B372ACB97AC6E433B938C2E9D8826D' :
189 'Stephen Watson is a project admin for the ROX desktop, and has been involved with the '
190 'project since 2000. This key has been used for signing software since the 23 Jul 2005 '
191 'announcement on the zero-install mailing list.',
193 'F0A0CA2A8D8FCC123F5EC04CD8D59DC384AE988E' :
194 'Piero Ottuzzi is experimenting with packaging programs for 0launch. This key has been '
195 'known since a 16 Mar 2005 post to the zero-install mailing list. It was first used to '
196 'sign software in an announcement posted on 9 Aug 2005.',