Merge ~jibel/ubiquity:encryption_recovery_key into ubiquity:master

Proposed by Jean-Baptiste Lallement
Status: Merged
Merge reported by: Michael Hudson-Doyle
Merged at revision: ea93e5b1aa4c43e34b64e72c9c382dc8d0d8630d
Proposed branch: ~jibel/ubiquity:encryption_recovery_key
Merge into: ubiquity:master
Diff against target: 748 lines (+395/-70)
6 files modified
debian/changelog (+7/-0)
debian/ubiquity.templates (+36/-2)
gui/gtk/stepPartCrypto.ui (+268/-58)
tests/test_gtkui.py (+2/-1)
ubiquity/plugins/ubi-partman.py (+76/-9)
ubiquity/validation.py (+6/-0)
Reviewer Review Type Date Requested Status
Didier Roche-Tolomelli (community) Approve
Ubuntu Installer Team Pending
Review via email: mp+403553@code.launchpad.net

Commit message

Make the recovery key editable and optional.
Make default recovery key 48 digits long.

Description of the change

This is an update of the recovery key feature that landed in previous release (21.04)

This updated version brings the following changes:
 * the recovery key is optional.
 * the recovery key is editable.
 * the default recovery key is a 48 digits number.

It also fixes an issue where the recovery key fields were not displayed in manual partitioning mode with an encrypted partition.

The default key is now generated with 'secrets' instead of uuid4().

The layout of the UI has been adapted a bit to fit on a small screen but one test had to be updated to relax the constraint on the minimal screen height.

The package builds in a PPA:
https://launchpad.net/~jibel/+archive/ubuntu/ppa/+build/21620546

The package has been tested in a VM on Ubuntu Desktop.

To post a comment you must log in.
ea93e5b... by Jean-Baptiste Lallement

Reformat changelog and removed comments

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

With latest changes, LGTM! Thanks.

review: Approve
Revision history for this message
Sebastien Bacher (seb128) wrote :

it seems like the change there got merged, unsure why launchpad didn't change the status but could someone from the ubiquity team close it now?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 96772f9..b7d7a6a 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+ubiquity (21.10.2) UNRELEASED; urgency=medium
7+
8+ * Recovery key: 48 digits number by default, optional and editable
9+ (LP: #1928860)
10+
11+ -- Jean-Baptiste Lallement <jean-baptiste.lallement@ubuntu.com> Mon, 31 May 2021 14:21:30 +0200
12+
13 ubiquity (21.10.1) impish; urgency=medium
14
15 * choose-mirror: hirsute -> impish
16diff --git a/debian/ubiquity.templates b/debian/ubiquity.templates
17index 1d7d3ed..5fcc8c8 100644
18--- a/debian/ubiquity.templates
19+++ b/debian/ubiquity.templates
20@@ -1723,10 +1723,20 @@ Template: ubiquity/text/domain_connection_error
21 Type: text
22 _Description: Failed to connect to domain.
23
24-Template: ubiquity/text/show_recovery_key_location_label
25+Template: ubiquity/text/recovery_key_enable
26 Type: text
27 _Description:
28- Show recovery key:
29+ Enable recovery key:
30+
31+Template: ubiquity/text/recovery_key_label
32+Type: text
33+_Description:
34+ Recovery key:
35+
36+Template: ubiquity/text/verified_recovery_key_label
37+Type: text
38+_Description:
39+ Confirm recovery key:
40
41 Template: ubiquity/text/show_recovery_key
42 Type: text
43@@ -1763,3 +1773,27 @@ Template: ubiquity/text/recovery_key_filename
44 Type: text
45 _Description:
46 Enter recovery key filename
47+
48+Template: ubiquity/text/recovery_mismatch
49+Type: text
50+_Description: Passwords do not match
51+
52+Template: ubiquity/text/recovery_too_short
53+Type: text
54+_Description: Short password
55+
56+Template: ubiquity/text/recovery_weak
57+Type: text
58+_Description: Weak password
59+
60+Template: ubiquity/text/recovery_fair
61+Type: text
62+_Description: Fair password
63+
64+Template: ubiquity/text/recovery_good
65+Type: text
66+_Description: Good password
67+
68+Template: ubiquity/text/recovery_strong
69+Type: text
70+_Description: Strong password
71diff --git a/gui/gtk/stepPartCrypto.ui b/gui/gtk/stepPartCrypto.ui
72index e8ba049..a0734c5 100644
73--- a/gui/gtk/stepPartCrypto.ui
74+++ b/gui/gtk/stepPartCrypto.ui
75@@ -20,7 +20,7 @@
76 <property name="left-padding">24</property>
77 <property name="right-padding">24</property>
78 <child>
79- <!-- n-columns=2 n-rows=10 -->
80+ <!-- n-columns=2 n-rows=11 -->
81 <object class="GtkGrid" id="crypto_grid">
82 <property name="visible">True</property>
83 <property name="can-focus">False</property>
84@@ -61,7 +61,8 @@
85 <property name="halign">start</property>
86 <property name="label" translatable="yes">Disk encryption protects your files in case you lose your computer. It requires you to enter a security key each time the computer starts up.</property>
87 <property name="wrap">True</property>
88- <property name="max-width-chars">132</property>
89+ <property name="width-chars">92</property>
90+ <property name="max-width-chars">92</property>
91 <property name="xalign">0</property>
92 </object>
93 <packing>
94@@ -75,15 +76,16 @@
95 <property name="visible">True</property>
96 <property name="can-focus">False</property>
97 <property name="halign">start</property>
98- <property name="label" translatable="yes">&lt;span foreground="darkred"&gt;Warning:&lt;/span&gt; If you lose your personal security key and recovery key, all data will be lost.
99-</property>
100+ <property name="label" translatable="yes">&lt;span foreground="darkred"&gt;Warning:&lt;/span&gt; If you lose your personal security key and recovery key, all data will be lost.</property>
101 <property name="use-markup">True</property>
102 <property name="wrap">True</property>
103+ <property name="width-chars">92</property>
104+ <property name="max-width-chars">92</property>
105 <property name="xalign">0</property>
106 </object>
107 <packing>
108 <property name="left-attach">0</property>
109- <property name="top-attach">7</property>
110+ <property name="top-attach">8</property>
111 <property name="width">2</property>
112 </packing>
113 </child>
114@@ -103,7 +105,7 @@
115 </packing>
116 </child>
117 <child>
118- <!-- n-columns=3 n-rows=3 -->
119+ <!-- n-columns=3 n-rows=2 -->
120 <object class="GtkGrid" id="password_grid">
121 <property name="visible">True</property>
122 <property name="can-focus">False</property>
123@@ -113,11 +115,10 @@
124 <object class="GtkEntry" id="password">
125 <property name="visible">True</property>
126 <property name="can-focus">True</property>
127- <property name="hexpand">True</property>
128 <property name="visibility">False</property>
129 <property name="invisible-char">●</property>
130 <property name="activates-default">True</property>
131- <property name="width-chars">20</property>
132+ <property name="width-chars">36</property>
133 <signal name="changed" handler="info_loop" swapped="no"/>
134 </object>
135 <packing>
136@@ -129,11 +130,10 @@
137 <object class="GtkEntry" id="verified_password">
138 <property name="visible">True</property>
139 <property name="can-focus">True</property>
140- <property name="hexpand">True</property>
141 <property name="visibility">False</property>
142 <property name="invisible-char">●</property>
143 <property name="activates-default">True</property>
144- <property name="width-chars">20</property>
145+ <property name="width-chars">36</property>
146 <signal name="changed" handler="info_loop" swapped="no"/>
147 </object>
148 <packing>
149@@ -148,7 +148,7 @@
150 <property name="show-tabs">False</property>
151 <property name="show-border">False</property>
152 <child>
153- <object class="GtkFixed" id="empty">
154+ <object class="GtkFixed" id="password/empty">
155 <property name="visible">True</property>
156 <property name="can-focus">False</property>
157 </object>
158@@ -272,6 +272,7 @@
159 <property name="visible">True</property>
160 <property name="can-focus">False</property>
161 <property name="label" translatable="yes">Mismatch</property>
162+ <property name="wrap">True</property>
163 <property name="xalign">0</property>
164 <attributes>
165 <attribute name="scale" value="0.83333333333329995"/>
166@@ -308,15 +309,6 @@
167 <child>
168 <placeholder/>
169 </child>
170- <child>
171- <placeholder/>
172- </child>
173- <child>
174- <placeholder/>
175- </child>
176- <child>
177- <placeholder/>
178- </child>
179 </object>
180 <packing>
181 <property name="left-attach">1</property>
182@@ -335,12 +327,12 @@
183 </object>
184 <packing>
185 <property name="left-attach">0</property>
186- <property name="top-attach">8</property>
187+ <property name="top-attach">9</property>
188 </packing>
189 </child>
190 <child>
191 <object class="GtkCheckButton" id="crypto_overwrite_space">
192- <property name="label" translatable="yes">Overwrite the available space first</property>
193+ <property name="label" translatable="yes">Overwrite the available space first.</property>
194 <property name="use-action-appearance">False</property>
195 <property name="visible">True</property>
196 <property name="can-focus">True</property>
197@@ -350,21 +342,6 @@
198 </object>
199 <packing>
200 <property name="left-attach">1</property>
201- <property name="top-attach">8</property>
202- </packing>
203- </child>
204- <child>
205- <object class="GtkLabel" id="crypto_extra_time">
206- <property name="visible">True</property>
207- <property name="can-focus">False</property>
208- <property name="margin-left">24</property>
209- <property name="label" translatable="yes">&lt;span weight="light" size="small"&gt;The installation may take much longer.&lt;/span&gt;</property>
210- <property name="use-markup">True</property>
211- <property name="single-line-mode">True</property>
212- <property name="xalign">0</property>
213- </object>
214- <packing>
215- <property name="left-attach">1</property>
216 <property name="top-attach">9</property>
217 </packing>
218 </child>
219@@ -373,15 +350,16 @@
220 <property name="visible">True</property>
221 <property name="can-focus">False</property>
222 <property name="halign">start</property>
223- <property name="label" translatable="yes">A recovery key is generated and will be temporarily saved on the live system. You can select an alternate location. Save this file and keep it in a safe place elsewhere before rebooting. </property>
224+ <property name="margin-top">18</property>
225+ <property name="label" translatable="yes">A recovery key is generated and will be temporarily saved on the live system. You can enter your own and can select an alternate location. Save this file and keep it in a safe place elsewhere before rebooting. </property>
226 <property name="wrap">True</property>
227- <property name="max-width-chars">132</property>
228+ <property name="width-chars">72</property>
229+ <property name="max-width-chars">72</property>
230 <property name="xalign">0</property>
231 </object>
232 <packing>
233- <property name="left-attach">0</property>
234+ <property name="left-attach">1</property>
235 <property name="top-attach">4</property>
236- <property name="width">2</property>
237 </packing>
238 </child>
239 <child>
240@@ -395,7 +373,7 @@
241 </object>
242 <packing>
243 <property name="left-attach">0</property>
244- <property name="top-attach">5</property>
245+ <property name="top-attach">7</property>
246 </packing>
247 </child>
248 <child>
249@@ -437,32 +415,79 @@
250 </object>
251 <packing>
252 <property name="left-attach">1</property>
253+ <property name="top-attach">7</property>
254+ </packing>
255+ </child>
256+ <child>
257+ <object class="GtkLabel" id="recovery_key_label">
258+ <property name="visible">True</property>
259+ <property name="can-focus">False</property>
260+ <property name="label" translatable="yes">Recovery key:</property>
261+ <property name="justify">right</property>
262+ <property name="single-line-mode">True</property>
263+ <property name="xalign">1</property>
264+ </object>
265+ <packing>
266+ <property name="left-attach">0</property>
267 <property name="top-attach">5</property>
268 </packing>
269 </child>
270 <child>
271- <object class="GtkBox" id="show_key_box">
272+ <object class="GtkLabel" id="verified_recovery_key_label">
273+ <property name="visible">True</property>
274+ <property name="can-focus">False</property>
275+ <property name="label" translatable="yes">Confirm the recovery key:</property>
276+ <property name="justify">right</property>
277+ <property name="single-line-mode">True</property>
278+ <property name="xalign">1</property>
279+ </object>
280+ <packing>
281+ <property name="left-attach">0</property>
282+ <property name="top-attach">6</property>
283+ </packing>
284+ </child>
285+ <child>
286+ <object class="GtkCheckButton" id="recovery_key_enable">
287+ <property name="label" translatable="yes">Enable recovery key</property>
288+ <property name="visible">True</property>
289+ <property name="can-focus">True</property>
290+ <property name="receives-default">False</property>
291+ <property name="valign">start</property>
292+ <property name="margin-top">18</property>
293+ <property name="draw-indicator">True</property>
294+ <signal name="toggled" handler="on_recovery_key_enable_toggled" swapped="no"/>
295+ </object>
296+ <packing>
297+ <property name="left-attach">0</property>
298+ <property name="top-attach">4</property>
299+ </packing>
300+ </child>
301+ <child>
302+ <!-- n-columns=3 n-rows=2 -->
303+ <object class="GtkGrid" id="recovery_grid">
304 <property name="visible">True</property>
305 <property name="can-focus">False</property>
306+ <property name="row-spacing">6</property>
307+ <property name="column-spacing">6</property>
308 <child>
309 <object class="GtkEntry" id="recovery_key">
310 <property name="visible">True</property>
311 <property name="can-focus">True</property>
312- <property name="editable">False</property>
313 <property name="visibility">False</property>
314 <property name="invisible-char">●</property>
315 <property name="activates-default">True</property>
316- <property name="width-chars">30</property>
317+ <property name="width-chars">36</property>
318 <property name="secondary-icon-name">view-reveal-symbolic</property>
319 <property name="primary-icon-activatable">False</property>
320 <property name="primary-icon-sensitive">False</property>
321 <property name="secondary-icon-tooltip-text" translatable="yes"> </property>
322+ <property name="secondary-icon-tooltip-markup" translatable="yes"> </property>
323+ <signal name="changed" handler="info_loop" swapped="no"/>
324 <signal name="icon-press" handler="on_recovery_key_toggle_visibility" swapped="no"/>
325 </object>
326 <packing>
327- <property name="expand">False</property>
328- <property name="fill">True</property>
329- <property name="position">0</property>
330+ <property name="left-attach">0</property>
331+ <property name="top-attach">0</property>
332 </packing>
333 </child>
334 <child>
335@@ -474,29 +499,214 @@
336 <signal name="clicked" handler="on_recovery_key_generate_button" swapped="no"/>
337 </object>
338 <packing>
339- <property name="expand">False</property>
340- <property name="fill">True</property>
341- <property name="position">1</property>
342+ <property name="left-attach">1</property>
343+ <property name="top-attach">0</property>
344+ </packing>
345+ </child>
346+ <child>
347+ <object class="GtkEntry" id="verified_recovery_key">
348+ <property name="visible">True</property>
349+ <property name="can-focus">True</property>
350+ <property name="visibility">False</property>
351+ <property name="invisible-char">●</property>
352+ <property name="activates-default">True</property>
353+ <property name="width-chars">36</property>
354+ <property name="primary-icon-activatable">False</property>
355+ <property name="primary-icon-sensitive">False</property>
356+ <signal name="changed" handler="info_loop" swapped="no"/>
357+ </object>
358+ <packing>
359+ <property name="left-attach">0</property>
360+ <property name="top-attach">1</property>
361+ </packing>
362+ </child>
363+ <child>
364+ <object class="GtkNotebook" id="recovery_strength">
365+ <property name="visible">True</property>
366+ <property name="can-focus">False</property>
367+ <property name="hexpand">True</property>
368+ <property name="show-tabs">False</property>
369+ <property name="show-border">False</property>
370+ <child>
371+ <object class="GtkFixed" id="recovery/empty">
372+ <property name="visible">True</property>
373+ <property name="can-focus">False</property>
374+ </object>
375+ </child>
376+ <child type="tab">
377+ <placeholder/>
378+ </child>
379+ <child>
380+ <object class="GtkLabel" id="recovery_too_short">
381+ <property name="visible">True</property>
382+ <property name="can-focus">False</property>
383+ <property name="label" translatable="yes">Short password</property>
384+ <property name="xalign">0</property>
385+ <attributes>
386+ <attribute name="scale" value="0.83333333333329995"/>
387+ <attribute name="foreground" value="#8b8b00000000"/>
388+ </attributes>
389+ </object>
390+ <packing>
391+ <property name="position">1</property>
392+ </packing>
393+ </child>
394+ <child type="tab">
395+ <placeholder/>
396+ </child>
397+ <child>
398+ <object class="GtkLabel" id="recovery_weak">
399+ <property name="visible">True</property>
400+ <property name="can-focus">False</property>
401+ <property name="label" translatable="yes">Weak password</property>
402+ <property name="xalign">0</property>
403+ <attributes>
404+ <attribute name="scale" value="0.83333333333329995"/>
405+ <attribute name="foreground" value="#8b8b00000000"/>
406+ </attributes>
407+ </object>
408+ <packing>
409+ <property name="position">2</property>
410+ </packing>
411+ </child>
412+ <child type="tab">
413+ <placeholder/>
414+ </child>
415+ <child>
416+ <object class="GtkLabel" id="recovery_fair">
417+ <property name="visible">True</property>
418+ <property name="can-focus">False</property>
419+ <property name="label" translatable="yes">Fair password</property>
420+ <property name="xalign">0</property>
421+ <attributes>
422+ <attribute name="scale" value="0.83333333333329995"/>
423+ <attribute name="foreground" value="#ffff8c8c0000"/>
424+ </attributes>
425+ </object>
426+ <packing>
427+ <property name="position">3</property>
428+ </packing>
429+ </child>
430+ <child type="tab">
431+ <placeholder/>
432+ </child>
433+ <child>
434+ <object class="GtkLabel" id="recovery_good">
435+ <property name="visible">True</property>
436+ <property name="can-focus">False</property>
437+ <property name="label" translatable="yes">Good password</property>
438+ <property name="xalign">0</property>
439+ <attributes>
440+ <attribute name="scale" value="0.83333333333329995"/>
441+ <attribute name="foreground" value="#000064640000"/>
442+ </attributes>
443+ </object>
444+ <packing>
445+ <property name="position">4</property>
446+ </packing>
447+ </child>
448+ <child type="tab">
449+ <placeholder/>
450+ </child>
451+ <child>
452+ <object class="GtkLabel" id="recovery_strong">
453+ <property name="visible">True</property>
454+ <property name="can-focus">False</property>
455+ <property name="label" translatable="yes">Strong password</property>
456+ <property name="xalign">0</property>
457+ <attributes>
458+ <attribute name="scale" value="0.83333333333329995"/>
459+ <attribute name="foreground" value="#000064640000"/>
460+ </attributes>
461+ </object>
462+ <packing>
463+ <property name="position">5</property>
464+ </packing>
465+ </child>
466+ <child type="tab">
467+ <placeholder/>
468+ </child>
469+ </object>
470+ <packing>
471+ <property name="left-attach">2</property>
472+ <property name="top-attach">0</property>
473+ </packing>
474+ </child>
475+ <child>
476+ <object class="GtkNotebook" id="recovery_match">
477+ <property name="visible">True</property>
478+ <property name="can-focus">False</property>
479+ <property name="hexpand">True</property>
480+ <property name="show-tabs">False</property>
481+ <property name="show-border">False</property>
482+ <child>
483+ <object class="GtkFixed" id="recovery_empty2">
484+ <property name="visible">True</property>
485+ <property name="can-focus">False</property>
486+ </object>
487+ </child>
488+ <child type="tab">
489+ <placeholder/>
490+ </child>
491+ <child>
492+ <object class="GtkLabel" id="recovery_mismatch">
493+ <property name="visible">True</property>
494+ <property name="can-focus">False</property>
495+ <property name="label" translatable="yes">Mismatch</property>
496+ <property name="wrap">True</property>
497+ <property name="xalign">0</property>
498+ <attributes>
499+ <attribute name="scale" value="0.83333333333329995"/>
500+ <attribute name="foreground" value="#8b8b00000000"/>
501+ </attributes>
502+ </object>
503+ <packing>
504+ <property name="position">1</property>
505+ </packing>
506+ </child>
507+ <child>
508+ <object class="GtkImage" id="recovery_ok">
509+ <property name="visible">True</property>
510+ <property name="can-focus">False</property>
511+ <property name="xalign">0</property>
512+ <property name="stock">gtk-apply</property>
513+ </object>
514+ <packing>
515+ <property name="position">2</property>
516+ </packing>
517+ </child>
518+ <child type="tab">
519+ <placeholder/>
520+ </child>
521+ </object>
522+ <packing>
523+ <property name="left-attach">2</property>
524+ <property name="top-attach">1</property>
525 </packing>
526 </child>
527+ <child>
528+ <placeholder/>
529+ </child>
530 </object>
531 <packing>
532 <property name="left-attach">1</property>
533- <property name="top-attach">6</property>
534+ <property name="top-attach">5</property>
535+ <property name="height">2</property>
536 </packing>
537 </child>
538 <child>
539- <object class="GtkLabel" id="show_recovery_key_location_label">
540+ <object class="GtkLabel" id="crypto_extra_time">
541 <property name="visible">True</property>
542 <property name="can-focus">False</property>
543- <property name="label" translatable="yes">Show recovery key:</property>
544- <property name="justify">right</property>
545+ <property name="margin-left">24</property>
546+ <property name="label" translatable="yes">&lt;span weight="light" size="small"&gt;The installation may take much longer.&lt;/span&gt;</property>
547+ <property name="use-markup">True</property>
548 <property name="single-line-mode">True</property>
549- <property name="xalign">1</property>
550+ <property name="xalign">0</property>
551 </object>
552 <packing>
553- <property name="left-attach">0</property>
554- <property name="top-attach">6</property>
555+ <property name="left-attach">1</property>
556+ <property name="top-attach">10</property>
557 </packing>
558 </child>
559 <child>
560diff --git a/tests/test_gtkui.py b/tests/test_gtkui.py
561index 215ab18..a33829d 100644
562--- a/tests/test_gtkui.py
563+++ b/tests/test_gtkui.py
564@@ -71,7 +71,7 @@ class TestFrontend(unittest.TestCase):
565 # Anything smaller will need to use Alt+Ctrl+Pgd/Right
566 # Scrollbars anyone?
567 # self.assertLessEqual(alloc.width, 640, page.module.NAME) # fixme
568- self.assertLessEqual(alloc.height, 556, page.module.NAME)
569+ self.assertLessEqual(alloc.height, 744, page.module.NAME) # 768 - 24px (top panel)
570 if page.module.NAME == 'partman':
571 ui.allow_change_step(False)
572
573@@ -121,6 +121,7 @@ class TestFrontend(unittest.TestCase):
574 # setup page.
575 'password_strength', 'hostname_error_label',
576 'password_error_label', 'username_error_label',
577+ 'recovery_strength',
578 # Pulled straight from debconf into the UI on progress.
579 'install_progress_text',
580 # Contains just the traceback.
581diff --git a/ubiquity/plugins/ubi-partman.py b/ubiquity/plugins/ubi-partman.py
582index fd7efa8..521ab06 100644
583--- a/ubiquity/plugins/ubi-partman.py
584+++ b/ubiquity/plugins/ubi-partman.py
585@@ -148,7 +148,7 @@ class PageGtk(PageBase):
586 for wdg in all_widgets:
587 setattr(self, wdg, builder.get_object(wdg))
588
589- # Crypto page
590+ # Crypto page, used for both primary and recovery keys
591 self.password_strength_pages = {
592 'empty': 0,
593 'too_short': 1,
594@@ -213,12 +213,12 @@ class PageGtk(PageBase):
595 # Define a list to save grub imformation
596 self.grub_options = []
597
598- from gi.repository import Pango
599- self.recovery_key.modify_font(Pango.font_description_from_string('monospace'))
600 default_recovery_key_location = os.path.join(misc.get_live_user_home(), 'recovery.key')
601 self.recovery_key_location.set_text(default_recovery_key_location)
602 self.recovery_key.set_visibility(False)
603 self.recovery_key.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, 'view-reveal-symbolic')
604+ self.verified_recovery_key.set_visibility(False)
605+ self.enable_recovery_key(False)
606
607 def on_link_clicked(self, widget, uri):
608 misc.launch_uri(uri)
609@@ -285,7 +285,14 @@ class PageGtk(PageBase):
610 return
611 crypto_widgets += [
612 ('verified_crypto_label', 'crypto_label', 'bottom', 1, 1),
613- ('crypto_warning', 'verified_crypto_label', 'bottom', 2, 1),
614+ ('recovery_key_enable', 'verified_crypto_label', 'bottom', 1, 1),
615+ ('recovery_key_warning', 'recovery_key_enable', 'right', 1, 1),
616+ ('recovery_grid', 'recovery_key_warning', 'bottom', 1, 2),
617+ ('recovery_key_label', 'recovery_grid', 'left', 1, 1),
618+ ('verified_recovery_key_label', 'recovery_key_label', 'bottom', 1, 1),
619+ ('recovery_key_location_label', 'verified_recovery_key_label', 'bottom', 1, 1),
620+ ('key_location_box', 'recovery_key_location_label', 'right', 1, 1),
621+ ('crypto_warning', 'recovery_key_location_label', 'bottom', 2, 1),
622 ('crypto_extra_label', 'crypto_warning', 'bottom', 1, 1),
623 ('crypto_overwrite_space', 'crypto_extra_label', 'right', 1, 1),
624 ('crypto_extra_time', 'crypto_overwrite_space', 'bottom', 1, 1)]
625@@ -302,9 +309,12 @@ class PageGtk(PageBase):
626 widget.show()
627
628 def generate_recovery_key(self):
629- from uuid import uuid4
630- key = str(uuid4().int >> 64)[:16]
631+ if not self.recovery_key_enable.get_active():
632+ return
633+ from secrets import randbelow
634+ key = str(randbelow(10**48)).zfill(48)
635 self.recovery_key.set_text(key)
636+ self.verified_recovery_key.set_text(key)
637
638 def on_advanced_features_clicked(self, widget):
639 from gi.repository import Gtk
640@@ -385,9 +395,34 @@ class PageGtk(PageBase):
641 from gi.repository import Gtk
642 visibility = self.recovery_key.get_visibility()
643 self.recovery_key.set_visibility(not visibility)
644+ self.verified_recovery_key.set_visibility(not visibility)
645 self.recovery_key.set_icon_from_icon_name(
646 Gtk.EntryIconPosition.SECONDARY, ('view-conceal-symbolic', 'view-reveal-symbolic')[visibility])
647
648+ def on_recovery_key_enable_toggled(self, widget):
649+ self.enable_recovery_key(widget.get_active())
650+
651+ def enable_recovery_key(self, enable=False):
652+ self.recovery_key_warning.set_sensitive(enable)
653+ self.recovery_key_label.set_sensitive(enable)
654+ self.recovery_key.set_sensitive(enable)
655+ self.recovery_key_generate_button.set_sensitive(enable)
656+ self.verified_recovery_key_label.set_sensitive(enable)
657+ self.verified_recovery_key.set_sensitive(enable)
658+ self.recovery_key_location_label.set_sensitive(enable)
659+ self.recovery_key_location.set_sensitive(enable)
660+ self.recovery_key_button.set_sensitive(enable)
661+
662+ if enable:
663+ self.generate_recovery_key()
664+ else:
665+ self.recovery_key.set_text("")
666+ self.verified_recovery_key.set_text("")
667+ self.recovery_strength.set_current_page(
668+ self.password_strength_pages['empty'])
669+ self.recovery_match.set_current_page(
670+ self.password_match_pages['empty'])
671+
672 def should_show_bitlocker_page(self):
673 return ('bitlocker' in self.extra_options or
674 os.environ.get('SHOW_BITLOCKER_UI', '0') == '1')
675@@ -1090,8 +1125,15 @@ class PageGtk(PageBase):
676 self.partition_dialog_okbutton.set_sensitive(True)
677
678 for widget in ['password_grid', 'crypto_label', 'crypto_warning',
679- 'verified_crypto_label', 'crypto_extra_label',
680- 'crypto_overwrite_space', 'crypto_extra_time']:
681+ 'verified_crypto_label',
682+ 'crypto_extra_label',
683+ 'crypto_overwrite_space', 'crypto_extra_time',
684+ 'recovery_key_enable', 'recovery_key_warning',
685+ 'recovery_grid',
686+ 'recovery_key_label',
687+ 'verified_recovery_key_label',
688+ 'recovery_key_location_label',
689+ 'key_location_box']:
690 getattr(getattr(self, widget), action)()
691
692 def show_overwrite_space(self, show_hide):
693@@ -1639,6 +1681,28 @@ class PageGtk(PageBase):
694 self.password_strength.set_current_page(
695 self.password_strength_pages['empty'])
696
697+ # Recovery key
698+ recovery = self.recovery_key.get_text()
699+ vrecovery = self.verified_recovery_key.get_text()
700+
701+ if recovery:
702+ if recovery != vrecovery:
703+ # It's okay to reuse complete since it'll stay False if it's
704+ # already false from previous check and switch to False
705+ # otherwise.
706+ # In either case, we don't want to proceed if the password or
707+ # the recovery are invalid.
708+ complete = False
709+ self.recovery_match.set_current_page(
710+ self.password_match_pages['mismatch'])
711+ else:
712+ self.recovery_match.set_current_page(
713+ self.password_match_pages['ok'])
714+
715+ txt = validation.human_password_strength(recovery)[0]
716+ self.recovery_strength.set_current_page(
717+ self.password_strength_pages[txt])
718+
719 self.controller.allow_go_forward(complete)
720 self.partition_dialog_okbutton.set_sensitive(complete)
721 return complete
722@@ -1662,7 +1726,10 @@ class PageGtk(PageBase):
723 return False
724
725 def get_recovery_keys(self):
726- return self.recovery_key.get_text()
727+ if self.info_loop(None):
728+ return self.recovery_key.get_text()
729+ else:
730+ return False
731
732
733 class PageKde(PageBase):
734diff --git a/ubiquity/validation.py b/ubiquity/validation.py
735index 9a08b4e..a782acc 100644
736--- a/ubiquity/validation.py
737+++ b/ubiquity/validation.py
738@@ -116,6 +116,12 @@ def password_strength(password):
739 strength = 1
740 if strength < 0:
741 strength = 0
742+
743+ # Recovery keys are 48 digits number and cannot be considered "fair"
744+ # so set it a level higher
745+ if len(password) >= 48 and strength < 0.75:
746+ strength = 0.8
747+
748 return strength
749
750

Subscribers

People subscribed via source and target branches