Merge lp:~joergberroth/ubuntu-system-settings/wifi-802-1x-configurations into lp:ubuntu-system-settings

Proposed by JkB
Status: Superseded
Proposed branch: lp:~joergberroth/ubuntu-system-settings/wifi-802-1x-configurations
Merge into: lp:ubuntu-system-settings
Diff against target: 1111 lines (+697/-255)
4 files modified
plugins/wifi/OtherNetwork.qml (+563/-246)
plugins/wifi/PageComponent.qml (+3/-3)
plugins/wifi/wifidbushelper.cpp (+129/-5)
plugins/wifi/wifidbushelper.h (+2/-1)
To merge this branch: bzr merge lp:~joergberroth/ubuntu-system-settings/wifi-802-1x-configurations
Reviewer Review Type Date Requested Status
Jonas G. Drange (community) Needs Fixing
Ubuntu Touch System Settings Pending
Review via email: mp+256739@code.launchpad.net

This proposal has been superseded by a proposal from 2015-04-25.

Commit message

Added support for 802-1x wireless network configurations.

Description of the change

Added support for 802-1x wireless network configurations.

To post a comment you must log in.
1388. By JkB

format

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

This is really great. Thanks for proposing this.

I've added some comments, but they're mostly about your decision to make the Dialog an ItemPage. If this is not crucial to the implementation of support for 802-1x, we need to revert it.

Also, if cert picking is not implemented, please remove all components that are unused. Please leave the UI bits in, but hide it with "visible: showAllUI". This way we can get strings translated.

Thanks again.

review: Needs Fixing
Revision history for this message
JkB (joergberroth) wrote :

> This is really great. Thanks for proposing this.
>
> I've added some comments, but they're mostly about your decision to make the
> Dialog an ItemPage. If this is not crucial to the implementation of support
> for 802-1x, we need to revert it.
>
> Also, if cert picking is not implemented, please remove all components that
> are unused. Please leave the UI bits in, but hide it with "visible:
> showAllUI". This way we can get strings translated.
>
> Thanks again.

Hey, thanks a lot for for reviewing.

First I had the concerns about pushing it to an ItemPage, too. Then, after dealing with the variety of different configurations, I found there would be an advantage if one changes to ItemPage. There is no need for the ItemPage from implementation point of view but there are configurations for which the user has to be asked up to two different certificates and an additional private key (TLS) and there can be different types of path2 authentication types for the different WPA Enterprise configurations.
So if we want the user to be able two choose all the different types of configurations, it seems to me that a dialog would get quite overloaded with ui inputs. And correct me if I'm wrong but scrolling, which certainly would be needed, seems not to be provided for the dialogs.
At the moment there are some pages in the cellular settings (e.g. APN) where one switched to ItemPages, too. So from design point of view it would keep consistent.

Maybe, based on these points, we can quickly discuss this again before I revert the change.

All other comments are clear. I will consider for the next commit.
I think the file picker would make selecting certificates even more comfortable but I will remove it as proposed, so one can work on that later.

Thanks again.

Joerg

1389. By JkB

Concidered Review Comments. This commit keeps ItemPage. Removed filepicker which can be implemented later.

1390. By JkB

reverted to dialog.

1391. By JkB

Added LEAP to security options. Added Anonymous Identities. Formatting. ToDo: ItemSelector and picker for Cert files; some PAC options; password flags.

1392. By JkB

Fixed weird "!==". Added basic FilePicker functionality.

1393. By JkB

Added CertificateHandling to list installed and add new certificates from OtherNetwork
Now uses ItemSelectors and dataModels. Certs can be added by calling ContentHub.

ToDos:
*improve list update for ItemSelectors
*Add handling for private keys and pac files.
*add password-flags
*add pac-Provisioning
*change? from blob to path scheme for nm configurations no that certs can be stored in a central place.

--- in wifi settings:
*Page (from PageComponents) to manage all installed certs and keys.

1394. By JkB

Improved certificate and key handling. List installed and add new certificates from OtherNetwork Dialog.
    Uses ItemSelectors and dataModels to select certs and keys. Certs and keys can be added by calling ContentHub.

    ToDos:
    *improve list update for ItemSelectors
    *Improve handling pac files.
    *change? from blob to path scheme for nm configurations no that certs can be stored in a central place.

    --- in wifi settings:
    *Page (from PageComponents) to manage all "installed" certs and keys.

1395. By JkB

Merge with trunk

1396. By JkB

merge with trunk.
Fixed bugs.

1397. By JkB

removed some bugs,
finally tested on my BQ Aquaris. At least for WPA and a WPA Enterprise TTLS/MCHAP2 connection.
Had no other networks around.

final changes:
*changed to path scheme for cert handling with networkmanager
*removed some further small bugs that made it finally work.

----
ToDos:
*Improve handling of pac Files.
*As suggested, cert and key managment for "installed" ones will be needed.
*Improve CertDialog not to show raw content of cert.
*Implement network encryption detection to use dialog for visible networks as well.

1398. By JkB

merge with trunk
----
*added checks against bad cert/key content
*improved data update.

1399. By JkB

OtherNetwork extensions mature now.
---
*improved Pac fIle handling.

1400. By JkB

*

1401. By JkB

formatting

1402. By JkB

* ItemSelectors: select back to "None" as standard for cases when filePicker is canceled.
* formatting
----
ToDo (later on):
- change selectedIndex to Item that has been added via ContentHub.

1403. By JkB

merge with trunk

1404. By JkB

* improve config handling
* fixed bug: added missing nul termination to successfully store certs with path scheme.

1405. By JkB

* added QStandardPaths for cert handling
* improved getting secrets in Previous network to get wpa-eap passwords as well.
* restored .bzrignore

1406. By JkB

merge with trunk

1407. By JkB

merged with jgdx merge proposal. Thanks a lot Jonas for the extensive format fixes!
+Also, considered some quickly managable FIXMEs from Jonas. Some stay.

1408. By JkB

* fixed wpa-eap/peap configurations.
* added "certificates recommended" security hint.

1409. By JkB

*merged with trunk

1410. By JkB

merge jonas branch

1411. By JkB

merge with trunk

1412. By JkB

* set feedback back to original implementation

1413. By JkB

merge Jonas fixmes

1414. By JkB

clear spaces

1415. By JkB

merge with trunk

1416. By JkB

* multiple %1 args in i18n.tr all fall back to the first arg() provided.
Is this an individuell problem of my build?
If not we should consider this last commit.

1417. By JkB

* only show "using certificate.." hint if selected one == "None"

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/wifi/OtherNetwork.qml'
2--- plugins/wifi/OtherNetwork.qml 2015-01-09 08:47:53 +0000
3+++ plugins/wifi/OtherNetwork.qml 2015-04-25 17:07:51 +0000
4@@ -23,237 +23,550 @@
5 import Ubuntu.SystemSettings.Wifi 1.0
6 import QMenuModel 0.1
7
8-Component {
9-
10- Dialog {
11-
12- id: otherNetworkDialog
13- objectName: "otherNetworkDialog"
14- anchorToKeyboard: true
15-
16- function settingsValid() {
17- if(networkname.length == 0) {
18- return false;
19- }
20- if(securityList.selectedIndex == 0) {
21- return true
22- }
23- if(securityList.selectedIndex == 1) {
24- return password.length >= 8
25- }
26+ItemPage {
27+ id: otherNetworkItemPage
28+ objectName: "otherNetworkItemPage"
29+ title: i18n.tr("Connect to Hidden Network")
30+ flickable: scrollWidget
31+
32+ function settingsValid() {//#jkb: maybe more checks for added alternatives...
33+ if(networkname.length == 0) {
34+ return false;
35+ }
36+ if(securityList.selectedIndex == 0) {
37+ return true
38+ }
39+ if(securityList.selectedIndex == 3) {
40 // WEP
41 return password.length === 5 ||
42 password.length === 10 ||
43 password.length === 13 ||
44 password.length === 26;
45 }
46-
47- title: i18n.tr("Connect to Hidden Network")
48- text: feedback.enabled ? feedback.text : "";
49-
50- Common {
51- id: common
52- }
53-
54- states: [
55- State {
56- name: "CONNECTING"
57- PropertyChanges {
58- target: connectAction
59- enabled: false
60- }
61- PropertyChanges {
62- target: connectButtonIndicator
63- running: true
64- }
65- PropertyChanges {
66- target: passwordVisibleSwitch
67- enabled: false
68- }
69- PropertyChanges {
70- target: passwordVisibleLabel
71- opacity: 0.5
72- }
73- PropertyChanges {
74- target: password
75- enabled: false
76- }
77- PropertyChanges {
78- target: passwordListLabel
79- opacity: 0.5
80- }
81- PropertyChanges {
82- target: securityList
83- enabled: false
84- opacity: 0.5
85- }
86- PropertyChanges {
87- target: securityListLabel
88- opacity: 0.5
89- }
90- PropertyChanges {
91- target: networkname
92- enabled: false
93- }
94- PropertyChanges {
95- target: networknameLabel
96- opacity: 0.5
97- }
98- PropertyChanges {
99- target: feedback
100- enabled: true
101- }
102- },
103- State {
104- name: "FAILED"
105- PropertyChanges {
106- target: feedback
107- enabled: true
108- }
109- },
110- State {
111- name: "SUCCEEDED"
112- PropertyChanges {
113- target: successIndicator
114- running: true
115- }
116- PropertyChanges {
117- target: cancelButton
118- enabled: false
119- }
120- PropertyChanges {
121- target: connectAction
122- enabled: false
123- }
124- }
125- ]
126-
127- Label {
128- property bool enabled: false
129- id: feedback
130- horizontalAlignment: Text.AlignHCenter
131- height: contentHeight
132- wrapMode: Text.Wrap
133- visible: false
134- }
135-
136- Label {
137- id: networknameLabel
138- text : i18n.tr("Network name")
139- objectName: "networknameLabel"
140- fontSize: "medium"
141- font.bold: true
142- color: Theme.palette.selected.backgroundText
143- elide: Text.ElideRight
144- }
145-
146- TextField {
147- id : networkname
148- objectName: "networkname"
149- inputMethodHints: Qt.ImhNoPredictiveText
150- Component.onCompleted: forceActiveFocus()
151- }
152-
153- Label {
154- id: securityListLabel
155- text : i18n.tr("Security")
156- objectName: "securityListLabel"
157- fontSize: "medium"
158- font.bold: true
159- color: Theme.palette.selected.backgroundText
160- elide: Text.ElideRight
161- }
162-
163- ListItem.ItemSelector {
164- id: securityList
165- objectName: "securityList"
166- model: [i18n.tr("None"), // index: 0
167- i18n.tr("WPA & WPA2 Personal"), // index: 1
168- i18n.tr("WEP"), // index: 2
169- ]
170- }
171-
172- Label {
173- id: passwordListLabel
174- text : i18n.tr("Password")
175- objectName: "passwordListLabel"
176- fontSize: "medium"
177- font.bold: true
178- color: Theme.palette.selected.backgroundText
179- elide: Text.ElideRight
180- visible: securityList.selectedIndex !== 0
181- }
182-
183- TextField {
184- id : password
185- objectName: "password"
186- visible: securityList.selectedIndex !== 0
187- echoMode: passwordVisibleSwitch.checked ?
188- TextInput.Normal : TextInput.Password
189- inputMethodHints: Qt.ImhNoPredictiveText
190- onAccepted: {
191- connectAction.trigger();
192- }
193- }
194-
195- Row {
196- id: passwordVisiblityRow
197- layoutDirection: Qt.LeftToRight
198- spacing: units.gu(2)
199- visible: securityList.selectedIndex !== 0
200-
201- CheckBox {
202- id: passwordVisibleSwitch
203- activeFocusOnPress: false
204- }
205-
206- Label {
207- id: passwordVisibleLabel
208- text : i18n.tr("Show password")
209- objectName: "passwordVisibleLabel"
210- fontSize: "medium"
211- color: Theme.palette.selected.backgroundText
212- elide: Text.ElideRight
213- height: passwordVisibleSwitch.height
214- verticalAlignment: Text.AlignVCenter
215- MouseArea {
216- anchors {
217- fill: parent
218- }
219- onClicked: {
220- passwordVisibleSwitch.checked =
221- !passwordVisibleSwitch.checked
222- }
223- }
224- }
225- }
226-
227- RowLayout {
228- id: buttonRow
229+ // WPAs
230+ return password.length >= 8
231+ }
232+
233+ Common {
234+ id: common
235+ }
236+
237+ states: [
238+ State {
239+ name: "CONNECTING"
240+ PropertyChanges {
241+ target: connectAction
242+ enabled: false
243+ }
244+ PropertyChanges {
245+ target: connectButtonIndicator
246+ running: true
247+ }
248+
249+ PropertyChanges {
250+ target: p2authList
251+ enabled: false
252+ }
253+ PropertyChanges {
254+ target: p2authListLabel
255+ opacity: 0.5
256+ }
257+ PropertyChanges {
258+ target: cacert
259+ enabled: false
260+ }
261+ PropertyChanges {
262+ target: cacertLabel
263+ opacity: 0.5
264+ }
265+ PropertyChanges {
266+ target: passwordVisibleSwitch
267+ enabled: false
268+ }
269+ PropertyChanges {
270+ target: passwordVisibleLabel
271+ opacity: 0.5
272+ }
273+ PropertyChanges {
274+ target: password
275+ enabled: false
276+ }
277+ PropertyChanges {
278+ target: passwordLabel
279+ opacity: 0.5
280+ }
281+ PropertyChanges {
282+ target: username
283+ enabled: false
284+ }
285+ PropertyChanges {
286+ target: usernameLabel
287+ opacity: 0.5
288+ }
289+ PropertyChanges {
290+ target: authList
291+ enabled: false
292+ opacity: 0.5
293+ }
294+ PropertyChanges {
295+ target: authListLabel
296+ opacity: 0.5
297+ }
298+ PropertyChanges {
299+ target: securityList
300+ enabled: false
301+ opacity: 0.5
302+ }
303+ PropertyChanges {
304+ target: securityListLabel
305+ opacity: 0.5
306+ }
307+ PropertyChanges {
308+ target: networkname
309+ enabled: false
310+ }
311+ PropertyChanges {
312+ target: networknameLabel
313+ opacity: 0.5
314+ }
315+ PropertyChanges {
316+ target: feedback
317+ enabled: true
318+ visible: true
319+ }
320+ },
321+ State {
322+ name: "FAILED"
323+ PropertyChanges {
324+ target: feedback
325+ enabled: true
326+ visible: true
327+ }
328+ },
329+ State {
330+ name: "SUCCEEDED"
331+ PropertyChanges {
332+ target: successIndicator
333+ running: true
334+ }
335+
336+ PropertyChanges {
337+ target: connectAction
338+ enabled: false
339+ }
340+ }
341+ ]
342+
343+ Flickable { //from about/PageComponents.qml
344+ id: scrollWidget
345+ anchors.fill: parent
346+ contentHeight: units.gu(100)
347+ boundsBehavior: (contentHeight > otherNetworkItemPage.height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
348+ /* Set the direction to workaround https://bugreports.qt-project.org/browse/QTBUG-31905
349+ otherwise the UI might end up in a situation where scrolling doesn't work */
350+ flickableDirection: Flickable.VerticalFlick
351+
352+ Column{
353+
354+ spacing: units.gu(1)
355 anchors {
356- left: parent.left
357- right: parent.right
358- }
359- spacing: units.gu(2)
360- height: cancelButton.height
361-
362- Button {
363- id: cancelButton
364- objectName: "cancel"
365- Layout.fillWidth: true
366- text: i18n.tr("Cancel")
367- onClicked: {
368- PopupUtils.close(otherNetworkDialog);
369-
370- // If this dialog created the connection,
371- // disconnect the device
372- if (otherNetworkDialog.state === "CONNECTING") {
373- DbusHelper.forgetActiveDevice();
374- }
375- }
376- }
377-
378- Button {
379+ fill: parent
380+ margins: units.gu(2)
381+ }
382+
383+ Label {
384+ id: networknameLabel
385+ text : i18n.tr("Network name")
386+ objectName: "networknameLabel"
387+ fontSize: "medium"
388+ font.bold: false
389+ color: Theme.palette.selected.backgroundText
390+ elide: Text.ElideRight
391+ }
392+
393+ TextField {
394+ id : networkname
395+ objectName: "networkname"
396+ width: parent.width
397+ placeholderText: i18n.tr("SSID")
398+ inputMethodHints: Qt.ImhNoPredictiveText
399+ Component.onCompleted: forceActiveFocus()
400+ }
401+
402+ ListItem.ThinDivider {}
403+
404+ Label {
405+ id: securityListLabel
406+ text : i18n.tr("Security")
407+ objectName: "securityListLabel"
408+ fontSize: "medium"
409+ font.bold: false
410+ color: Theme.palette.selected.backgroundText
411+ elide: Text.ElideRight
412+ }
413+
414+ ListItem.ItemSelector {
415+ id: securityList
416+ objectName: "securityList"
417+ model: [i18n.tr("None"), // index: 0
418+ i18n.tr("WPA & WPA2 Personal"), // index: 1
419+ i18n.tr("WPA & WPA2 Enterprise"),// index: 2
420+ i18n.tr("WEP"), // index: 3
421+ i18n.tr("Dynamic WEP (802.1x)"), // index: 4
422+ ]
423+ }
424+
425+ Label {
426+ id: authListLabel
427+ text : i18n.tr("Authentication")
428+ objectName: "authListLabel"
429+ fontSize: "medium"
430+ font.bold: false
431+ color: Theme.palette.selected.backgroundText
432+ elide: Text.ElideRight
433+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
434+ }
435+
436+ ListItem.ItemSelector {
437+ id: authList
438+ objectName: "authList"
439+ model: [i18n.tr("TLS"), // index: 0
440+ i18n.tr("TTLS"), // index: 1
441+ i18n.tr("LEAP"), // index: 2
442+ i18n.tr("FAST"), // index: 3
443+ i18n.tr("PEAP"), // index: 4
444+ ]
445+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
446+ }
447+
448+ Label {
449+ id: p2authListLabel
450+ text : i18n.tr("Phase-2-Authentication")
451+ objectName: "p2authLabel"
452+ fontSize: "medium"
453+ font.bold: false
454+ color: Theme.palette.selected.backgroundText
455+ elide: Text.ElideRight
456+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4) // WPA or D-WEP
457+ && ( authList.selectedIndex == 1 ||
458+ authList.selectedIndex == 3 ||
459+ authList.selectedIndex == 4 )
460+ }
461+
462+ ListItem.ItemSelector {
463+ id: p2authList
464+ objectName: "p2authList"
465+ width: parent.width
466+ model: [i18n.tr("PAP"), // index: 0
467+ i18n.tr("MSCHAPv2"), // index: 1
468+ i18n.tr("MSCHAP"), // index: 2
469+ i18n.tr("CHAP"), // index: 3
470+ i18n.tr("GTC"), // index: 4
471+ i18n.tr("MD5") // index: 5
472+ ]
473+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4) // WPA or D-WEP
474+ && ( authList.selectedIndex == 1 ||
475+ authList.selectedIndex == 3 ||
476+ authList.selectedIndex == 4 )
477+ }
478+
479+ Column{ // ca-cert
480+ id: cacertColumn
481+ anchors {
482+ left: parent.left
483+ right: parent.right
484+ }
485+ spacing: parent.spacing
486+
487+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
488+ && ( authList.selectedIndex == 0 ||
489+ authList.selectedIndex == 1 ||
490+ authList.selectedIndex == 4 )
491+
492+ RowLayout{
493+ spacing: units.gu(4)
494+ anchors {
495+ left: parent.left
496+ right: parent.right
497+ }
498+
499+ Label {
500+ id: cacertLabel
501+ text : i18n.tr("CA-Certificate")
502+ objectName: "cacertListLabel"
503+ fontSize: "medium"
504+ font.bold: false
505+ color: Theme.palette.selected.backgroundText
506+ //anchors.bottom: addcacertButton.bottom // while button is disabled
507+ }
508+
509+ Button {
510+ id: addcacertButton
511+ //action: selectPeer
512+ visible: showAllUI // Button action not implemented yet.
513+ objectName: "addcacertButton"
514+ anchors.right: parent.right
515+ text: i18n.tr("Add file…")
516+ }
517+ }
518+
519+
520+ TextArea {
521+ id : cacert
522+ objectName: "cacert"
523+ width: parent.width
524+ autoSize: true
525+ maximumLineCount: 4
526+ placeholderText: i18n.tr("Absolute path to cert file or clipboard content")
527+
528+ }
529+
530+ RowLayout{
531+ spacing: units.gu(4)
532+ anchors {
533+ left: parent.left
534+ right: parent.right
535+ }
536+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
537+ && ( authList.selectedIndex == 0 ) // only for TLS
538+
539+ Label {
540+ id: usercertLabel
541+ text : i18n.tr("User Certificate")
542+ objectName: "usercertListLabel"
543+ fontSize: "medium"
544+ font.bold: false
545+ color: Theme.palette.selected.backgroundText
546+ //anchors.bottom: addusercertButton.bottom
547+ }
548+
549+ Button {
550+ id: addusercertButton
551+ //action: selectPeer
552+ visible: showAllUI // Button action not implemented yet.
553+ objectName: "addusercertButton"
554+ anchors.right: parent.right
555+ text: i18n.tr("Add file…")
556+ }
557+ }
558+
559+ TextArea{
560+ id : usercert
561+ objectName: "usercert"
562+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
563+ && ( authList.selectedIndex == 0 )
564+ width: parent.width
565+ autoSize: true
566+ maximumLineCount: 4
567+ placeholderText: i18n.tr("Absolute path to cert file or clipboard content")
568+ }
569+
570+
571+ RowLayout{
572+ spacing: units.gu(4)
573+ anchors {
574+ left: parent.left
575+ right: parent.right
576+ }
577+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
578+ && ( authList.selectedIndex == 0 ) // only for TLS
579+
580+ Label {
581+ id: userprivatekeyLabel
582+ text : i18n.tr("User Private Key")
583+ objectName: "userprivatekeyLabel"
584+ fontSize: "medium"
585+ font.bold: false
586+ color: Theme.palette.selected.backgroundText
587+ //anchors.bottom: adduserprivatekeyButton.bottom
588+ }
589+
590+ Button {
591+ id: adduserprivatekeyButton
592+ //action: selectPeer
593+ visible: showAllUI // Button action not implemented yet
594+ objectName: "adduserprivatekeyButton"
595+ anchors.right: parent.right
596+ text: i18n.tr("Add file…")
597+ }
598+ }
599+
600+ TextArea {
601+ id : userprivatekey
602+ objectName: "userprivatekey"
603+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
604+ && ( authList.selectedIndex == 0 )
605+ width: parent.width
606+ autoSize: true
607+ maximumLineCount: 4
608+ placeholderText: i18n.tr("Absolute path to key or clipboard content")
609+ }
610+
611+ ListItem.ThinDivider {}
612+
613+ }
614+
615+ Column{ // pacFile
616+ id: pacFileColumn
617+ anchors {
618+ left: parent.left
619+ right: parent.right
620+ }
621+ spacing: parent.spacing
622+
623+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
624+ && ( authList.selectedIndex == 3 )
625+
626+ RowLayout{
627+ spacing: units.gu(4)
628+ anchors {
629+ left: parent.left
630+ right: parent.right
631+ }
632+
633+ Label {
634+ id: pacFileLabel
635+ text : i18n.tr("Pac File")
636+ objectName: "pacFileLabel"
637+ fontSize: "medium"
638+ font.bold: false
639+ color: Theme.palette.selected.backgroundText
640+ //anchors.bottom: adduserprivatekeyButton.bottom
641+ }
642+
643+ Button {
644+ id: addpacFileButton
645+ //action: selectPeer
646+ visible: showAllUI // Button action not implemented yet
647+ objectName: "addpacFileButton"
648+ anchors.right: parent.right
649+ text: i18n.tr("Add file…")
650+ }
651+ }
652+
653+ TextArea {
654+ id : pacFile
655+ objectName: "pacFile"
656+ width: parent.width
657+ autoSize: true
658+ maximumLineCount: 4
659+ placeholderText: i18n.tr("Absolute path to Pac File or clipboard content")
660+ }
661+
662+ ListItem.ThinDivider {}
663+
664+ }
665+
666+ Label {
667+ id: usernameLabel
668+ text : {
669+ if ( ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
670+ && ( authList.selectedIndex == 0 )) {
671+ i18n.tr("Identity")
672+ }
673+ else {
674+ i18n.tr("Username")
675+ }
676+ }
677+
678+ objectName: "usernameLabel"
679+ fontSize: "medium"
680+ font.bold: false
681+ color: Theme.palette.selected.backgroundText
682+ elide: Text.ElideRight
683+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
684+ }
685+
686+ TextField {
687+ id : username
688+ objectName: "username"
689+ width: parent.width
690+ visible: ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
691+ inputMethodHints: Qt.ImhNoPredictiveText
692+ Component.onCompleted: forceActiveFocus()
693+ onAccepted: {
694+ connectAction.trigger()
695+ }
696+ }
697+
698+ Label {
699+ id: passwordLabel
700+ text: {
701+ if ( ( securityList.selectedIndex == 2 || securityList.selectedIndex == 4)
702+ && ( authList.selectedIndex == 0 )) {
703+ i18n.tr("Private Key Password")
704+ } else {
705+ i18n.tr("Password")
706+ }
707+ }
708+
709+ objectName: "passwordListLabel"
710+ fontSize: "medium"
711+ font.bold: false
712+ color: Theme.palette.selected.backgroundText
713+ elide: Text.ElideRight
714+ visible: securityList.selectedIndex !== 0
715+ }
716+
717+ TextField {
718+ id : password
719+ objectName: "password"
720+ width: parent.width
721+ visible: securityList.selectedIndex !== 0
722+ echoMode: passwordVisibleSwitch.checked ?
723+ TextInput.Normal : TextInput.Password
724+ inputMethodHints: Qt.ImhNoPredictiveText
725+ onAccepted: {
726+ connectAction.trigger();
727+ }
728+ }
729+
730+ Row {
731+ id: passwordVisiblityRow
732+ layoutDirection: Qt.LeftToRight
733+ spacing: units.gu(2)
734+ visible: securityList.selectedIndex !== 0
735+
736+ CheckBox {
737+ id: passwordVisibleSwitch
738+ //activeFocusOnPress: false
739+ }
740+
741+ Label {
742+ id: passwordVisibleLabel
743+ text : i18n.tr("Show password")
744+ objectName: "passwordVisibleLabel"
745+ fontSize: "medium"
746+ color: Theme.palette.selected.backgroundText
747+ elide: Text.ElideRight
748+ height: passwordVisibleSwitch.height
749+ verticalAlignment: Text.AlignVCenter
750+ MouseArea {
751+ anchors {
752+ fill: parent
753+ }
754+ onClicked: {
755+ passwordVisibleSwitch.checked =
756+ !passwordVisibleSwitch.checked
757+ }
758+ }
759+ }
760+
761+ }
762+
763+
764+ ListItem.ThinDivider {visible: securityList.selectedIndex != 0}
765+
766+ Label {
767+ property bool enabled: false
768+ id: feedback
769+ horizontalAlignment: Text.AlignHCenter
770+ height: contentHeight
771+ wrapMode: Text.Wrap
772+ visible: false
773+ }
774+
775+ Button {
776 id: connectButton
777 objectName: "connect"
778 Layout.fillWidth: true
779@@ -283,16 +596,20 @@
780 }
781
782 Action {
783- id: connectAction
784- enabled: settingsValid()
785- onTriggered: {
786- DbusHelper.connect(
787- networkname.text,
788- securityList.selectedIndex,
789- password.text);
790- otherNetworkDialog.state = "CONNECTING";
791+ id: connectAction
792+ enabled: settingsValid()
793+ onTriggered: {
794+ DbusHelper.connect(
795+ networkname.text,
796+ securityList.selectedIndex,
797+ authList.selectedIndex,
798+ username.text,
799+ password.text,
800+ [cacert.text, usercert.text, userprivatekey.text, pacFile.text] ,
801+ p2authList.selectedIndex);
802+ otherNetworkItemPage.state = "CONNECTING";
803+ }
804 }
805- }
806
807 /* Timer that shows a tick in the connect button once we have
808 successfully connected. */
809@@ -301,13 +618,12 @@
810 interval: 2000
811 running: false
812 repeat: false
813- onTriggered: PopupUtils.close(otherNetworkDialog)
814 }
815
816 Connections {
817 target: DbusHelper
818 onDeviceStateChanged: {
819- if (otherNetworkDialog.state === "FAILED") {
820+ if (otherNetworkItemPage.state === "FAILED") {
821 /* Disconnect the device if it tries to reconnect after a
822 connection failure */
823 if (newState === 40) { // 40 = NM_DEVICE_STATE_PREPARE
824@@ -319,21 +635,22 @@
825 the CONNECTING state. This means that this Dialog will not
826 react to what other NetworkManager consumers do.
827 */
828- if (otherNetworkDialog.state === "CONNECTING") {
829+ if (otherNetworkItemPage.state === "CONNECTING") {
830 switch (newState) {
831- case 120:
832- feedback.text = common.reasonToString(reason);
833- otherNetworkDialog.state = "FAILED";
834- break;
835- case 100:
836- /* connection succeeded only if it was us that
837+ case 120:
838+ feedback.text = common.reasonToString(reason);
839+ otherNetworkItemPage.state = "FAILED";
840+ break;
841+ case 100:
842+ /* connection succeeded only if it was us that
843 created it */
844- otherNetworkDialog.state = "SUCCEEDED";
845- break;
846+ otherNetworkItemPage.state = "SUCCEEDED";
847+ break;
848 }
849 }
850 }
851 }
852- }
853-}
854+
855+ } //Flickable
856+} //ItemPage
857
858
859=== modified file 'plugins/wifi/PageComponent.qml'
860--- plugins/wifi/PageComponent.qml 2015-04-20 15:08:41 +0000
861+++ plugins/wifi/PageComponent.qml 2015-04-25 17:07:51 +0000
862@@ -142,9 +142,9 @@
863 text: i18n.tr("Connect to hidden network…")
864 visible : (actionGroup.actionObject.valid ?
865 actionGroup.actionObject.state : false)
866- onClicked: {
867- otherNetworLoader.source = "OtherNetwork.qml";
868- PopupUtils.open(otherNetworLoader.item);
869+ progression: true
870+ onClicked: {
871+ pageStack.push(Qt.resolvedUrl("OtherNetwork.qml"))
872 }
873 }
874
875
876=== modified file 'plugins/wifi/wifidbushelper.cpp'
877--- plugins/wifi/wifidbushelper.cpp 2014-10-10 14:10:52 +0000
878+++ plugins/wifi/wifidbushelper.cpp 2015-04-25 17:07:51 +0000
879@@ -37,15 +37,29 @@
880 typedef QMap<QString,QVariantMap> ConfigurationData;
881 Q_DECLARE_METATYPE(ConfigurationData)
882
883+
884 WifiDbusHelper::WifiDbusHelper(QObject *parent) : QObject(parent),
885 m_systemBusConnection(QDBusConnection::systemBus())
886 {
887 qDBusRegisterMetaType<ConfigurationData>();
888 }
889
890-void WifiDbusHelper::connect(QString ssid, int security, QString password)
891+
892+QByteArray WifiDbusHelper::getCertContent(QString filename){
893+ QFile file(filename);
894+ if (!file.open(QIODevice::ReadOnly)) {
895+ qWarning() << "Could not resolve Cert-File (" << filename << "): File does not exist or is empty." ;
896+ return QByteArray();
897+ }
898+ else {
899+ return file.readAll();
900+ }
901+}
902+
903+
904+void WifiDbusHelper::connect(QString ssid, int security, int auth, QString username, QString password, QStringList certs, int p2auth)
905 {
906- if(security<0 || security>2) {
907+ if((security<0 || security>4) || (auth<0 || auth>4) || (p2auth<0 || p2auth>5)) {
908 qWarning() << "Qml and C++ have gotten out of sync. Can't connect.\n";
909 return;
910 }
911@@ -66,8 +80,10 @@
912 // security:
913 // 0: None
914 // 1: WPA & WPA2 Personal
915- // 2: WEP
916- if (security != 0) {
917+ // 2: WPA Enterprise
918+ // 3: WEP
919+ // 4: Dynamic WEP
920+ if (!(security == 0)) { // WPA Enterprise or Dynamic WEP
921 wireless["security"] = QStringLiteral("802-11-wireless-security");
922
923 QVariantMap wireless_security;
924@@ -75,17 +91,119 @@
925 if (security == 1) {
926 wireless_security["key-mgmt"] = QStringLiteral("wpa-psk");
927 wireless_security["psk"] = password;
928- } else if (security == 2) {
929+ } else if (security == 3) {
930 wireless_security["key-mgmt"] = QStringLiteral("none");
931 wireless_security["auth-alg"] = QStringLiteral("open");
932 wireless_security["wep-key0"] = password;
933 wireless_security["wep-key-type"] = QVariant(uint(1));
934+ } else if (security == 2) {
935+ wireless_security["key-mgmt"] = QStringLiteral("wpa-eap");
936+ } else if (security == 4) {
937+ wireless_security["key-mgmt"] = QStringLiteral("ieee8021x");
938+
939+ /* leave disabled as hopefully not needed:
940+ QStringList wep_pairwise, wep_group;
941+ wep_pairwise[0] ="wep40"; wep_pairwise[1] ="wep104";
942+ wep_group[0] ="wep40"; wep_group[1] ="wep104";
943+ wireless_security["pairwise"] = wep_pairwise;
944+ wireless_security["group"] = wep_group; */
945 }
946 configuration["802-11-wireless-security"] = wireless_security;
947 }
948
949 configuration["802-11-wireless"] = wireless;
950
951+ if (security == 2 || security == 4){
952+
953+ QVariantMap wireless_802_1x;
954+ // [802-1x]
955+ /*TLS // index: 0
956+ TTLS // index: 1
957+ LEAP // index: 2
958+ FAST // index: 3
959+ PEAP // index: 4 */
960+
961+ wireless_802_1x["identity"] = username;
962+ if (!(auth == 0)) {
963+ wireless_802_1x["password"] = password;
964+ }
965+
966+ QByteArray cacert_a, clientcert, privatekey, pacFile;
967+
968+ if (certs[0].left(1) == "/"){
969+ cacert_a = getCertContent(certs[0]);
970+ }
971+ else {
972+ cacert_a.append(certs[0]);
973+ }
974+
975+ if (auth == 0) { // TLS
976+ wireless_802_1x["eap"] = QStringList("tls");
977+ wireless_802_1x["ca-cert"] = cacert_a;
978+
979+ if (certs[1].left(1) == "/"){
980+ clientcert = getCertContent(certs[1]);
981+ }
982+ else {
983+ clientcert.append(certs[1]);
984+ }
985+ wireless_802_1x["client-cert"] = clientcert;
986+ if (certs[2].left(1) == "/"){
987+ privatekey = getCertContent(certs[2]);
988+ }
989+ else {
990+ privatekey.append(certs[2]);
991+ }
992+ wireless_802_1x["private-key"] = privatekey;
993+ wireless_802_1x["private-key-password"] = password;
994+ } else if (auth == 1) { // TTLS
995+ wireless_802_1x["eap"] = QStringList("ttls");
996+ wireless_802_1x["ca-cert"] = cacert_a;
997+ } else if (auth == 2) { // LEAP
998+ wireless_802_1x["eap"] = QStringList("leap");
999+ } else if (auth == 3) { // FAST
1000+ wireless_802_1x["eap"] = QStringList("fast");
1001+ wireless_802_1x["ca-cert"] = cacert_a;
1002+
1003+ if (certs[3].left(1) == "/"){
1004+ pacFile = getCertContent(certs[3]);
1005+ }
1006+ else {
1007+ pacFile.append(certs[3]);
1008+ }
1009+ wireless_802_1x["pac-file"] = pacFile;
1010+
1011+ // wireless_802_1x["phase1-fast-provisioning"] = QString("0");
1012+ } else if (auth == 4) { // PEAP
1013+ wireless_802_1x["eap"] = QStringList("peap");
1014+ wireless_802_1x["phase1-peaplabel"] = QString("1");
1015+ //wireless_802_1x["phase1-peapver"] = QString("0"); #jkb:let us unset this until problems are reported.
1016+ }
1017+
1018+ if (auth == 1 || auth == 3 || auth == 4 ){ // only for TTLS, FAST and PEAP
1019+ /* PAP // index: 0
1020+ MSCHAPv2 // index: 1
1021+ MSCHAP // index: 2
1022+ CHAP // index: 3
1023+ GTC // index: 4
1024+ MD5 // index: 5 */
1025+ if (p2auth == 0) {
1026+ wireless_802_1x["phase2-auth"] = QStringLiteral("pap");
1027+ } else if (p2auth == 1) {
1028+ wireless_802_1x["phase2-auth"] = QStringLiteral("mschapv2");
1029+ } else if (p2auth == 2) {
1030+ wireless_802_1x["phase2-auth"] = QStringLiteral("mschap");
1031+ } else if (p2auth == 3) {
1032+ wireless_802_1x["phase2-auth"] = QStringLiteral("chap");
1033+ } else if (p2auth == 4) {
1034+ wireless_802_1x["phase2-auth"] = QStringLiteral("gtc");
1035+ } else if (p2auth == 5) {
1036+ wireless_802_1x["phase2-auth"] = QStringLiteral("md5");
1037+ }
1038+
1039+ }
1040+ configuration["802-1x"] = wireless_802_1x;
1041+ }
1042
1043 // find the first wlan adapter for now
1044 auto reply1 = mgr.GetDevices();
1045@@ -142,6 +260,7 @@
1046 }
1047 }
1048
1049+
1050 void WifiDbusHelper::nmDeviceStateChanged(uint newState,
1051 uint oldState,
1052 uint reason)
1053@@ -150,6 +269,7 @@
1054 Q_EMIT (deviceStateChanged(newState, reason));
1055 }
1056
1057+
1058 QString WifiDbusHelper::getWifiIpAddress()
1059 {
1060 OrgFreedesktopNetworkManagerInterface mgr(NM_SERVICE,
1061@@ -193,6 +313,7 @@
1062 return QString(inet_ntoa(ip_addr));
1063 }
1064
1065+
1066 struct Network : public QObject
1067 {
1068 struct DontCare : public std::exception {};
1069@@ -345,6 +466,7 @@
1070 QMap<QString, QVariantMap> settings;
1071 };
1072
1073+
1074 QList<QStringList> WifiDbusHelper::getPreviouslyConnectedWifiNetworks() {
1075 QList<QStringList> networks;
1076
1077@@ -383,6 +505,7 @@
1078 return networks;
1079 }
1080
1081+
1082 void WifiDbusHelper::forgetConnection(const QString dbus_path) {
1083 OrgFreedesktopNetworkManagerSettingsConnectionInterface bar
1084 (NM_SERVICE,
1085@@ -395,6 +518,7 @@
1086 }
1087 }
1088
1089+
1090 bool WifiDbusHelper::forgetActiveDevice() {
1091 OrgFreedesktopNetworkManagerInterface mgr(NM_SERVICE,
1092 NM_PATH,
1093
1094=== modified file 'plugins/wifi/wifidbushelper.h'
1095--- plugins/wifi/wifidbushelper.h 2014-10-10 14:10:52 +0000
1096+++ plugins/wifi/wifidbushelper.h 2015-04-25 17:07:51 +0000
1097@@ -37,7 +37,7 @@
1098 explicit WifiDbusHelper(QObject *parent = nullptr);
1099 ~WifiDbusHelper() {};
1100
1101- Q_INVOKABLE void connect(QString ssid, int security, QString password);
1102+ Q_INVOKABLE void connect(QString ssid, int security, int auth, QString username, QString password, QStringList certs, int p2auth);
1103 Q_INVOKABLE QList<QStringList> getPreviouslyConnectedWifiNetworks();
1104 Q_INVOKABLE void forgetConnection(const QString dbus_path);
1105 Q_INVOKABLE bool forgetActiveDevice();
1106@@ -52,6 +52,7 @@
1107 private:
1108 QDBusConnection m_systemBusConnection;
1109 QString getWifiIpAddress();
1110+ QByteArray getCertContent(QString filename);
1111 };
1112
1113

Subscribers

People subscribed via source and target branches