ACC SHELL
/**
* File: include/network/lan/wireless.ycp
* Package: Network configuration
* Summary: Wireless dialogs
* Authors: Michal Svec <msvec@suse.cz>
*
* $Id: wireless.ycp 59728 2009-11-24 12:07:37Z mzugec $
*/
{
textdomain "network";
import "CWM";
import "FileUtils";
import "Label";
import "Lan";
import "LanItems";
import "Map";
import "Message";
import "Popup";
import "String";
import "Wizard";
include "network/routines.ycp";
include "network/lan/help.ycp";
// key input type buttons
term type_w = `RadioButtonGroup (
`id (`type_g),
`VBox (
// Translators: input type for a wireless key
// radio button group label
`Left (`Label (_("Key Input Type"))),
`Left (`HBox (
// Translators: input type for a wireless key
`RadioButton (`id ("passphrase"), _("&Passphrase")),
`HSpacing (1),
// Translators: input type for a wireless key
`RadioButton (`id ("ascii"), _("&ASCII")),
`HSpacing (1),
// Translators: input type for a wireless key
// (Hexadecimal)
`RadioButton (`id ("hex"), _("&Hexadecimal"))))
)
);
/**
* Compose a typed key into a single-string representation
* @param type "passphrase", "ascii", "hex"
* @param key
* @return prefixed key
*/
define string ComposeWepKey (string type, string key) ``{
// prefixes for key types
map <string, string> prefix = $[
"ascii": "s:",
"passphrase": "h:",
"hex": "",
];
// empty key - don't prepend a type (#40431)
if (key == "")
{
return "";
}
else
{
return (prefix[type]:"?:") + key;
}
}
define map<string, string> ParseWepKey (string tkey) ``{
if (substring (tkey, 0, 2) == "s:")
{
return $[ "key": substring (tkey, 2), "type": "ascii", ];
}
else if (substring (tkey, 0, 2) == "h:")
{
return $[ "key": substring (tkey, 2), "type": "passphrase", ];
}
// make passphrase the default key type, #40431
else if (tkey == "")
{
return $[ "key": tkey, "type": "passphrase", ];
}
else
{
return $[ "key": tkey, "type": "hex", ];
}
}
/**
* Is the entered key valid?
* TODO: check according to the selected key length
* (or better adjust the length?)
* @param lengths allowed real key lengths
*/
define boolean CheckWirelessKey (string key, list<integer> lengths) {
if (key == nil)
{
return false;
}
if (regexpmatch (key, "^s:.{5}$") && contains (lengths, 40) ||
regexpmatch (key, "^s:.{6,13}$") && contains (lengths, 104))
{
return true;
}
if (regexpmatch (key, "^[0-9A-Fa-f-]*$"))
{
key = deletechars (key, "-");
integer actual_bits = size (key) * 4; // 4 bits per hex digit
if (contains (lengths, actual_bits))
{
return true;
}
y2milestone ("Key length: actual %1, allowed %2", actual_bits, lengths);
}
if (regexpmatch (key, "^h:"))
{
return true;
}
return false;
}
/**
* Takes the WEP items from the list and returns the key lengths as integers
* Like the input, uses the real length which is 24 bits shorter
* than the marketing one.
* If the input is nil, return the default set of key lengths.
* @param enc_modes a subset of WEP40, WEP104, WEP128, WEP232, TKIP, CCMP
* @return list of real key lengths
*/
list<integer> ParseKeyLengths (list<string> enc_modes) {
if (enc_modes == nil)
{
return [40, 104];
}
list<integer> lengths = [];
foreach (string em, enc_modes, {
if (substring (em, 0, 3) == "WEP")
{
lengths = add (lengths, tointeger (substring (em, 3)));
}
});
if (lengths == [])
{
y2warning ("empty set of key lengths");
}
return lengths;
}
/**
* Make a list of ComboBox items for authentication mode.
* We must translate WPA-PSK: it is "wpa-psk" in hwinfo but "psk" in syconfig
* (#74496).
* @param authmodes allowed modes as returned by hwinfo. nil == don't know.
* @return combo box items
*/
list<term> AuthModeItems (list<string> authmodes) {
map <string, string> names = $[
// Wireless authentication modes:
/* ComboBox item */
"no-encryption" : _("No Encryption"),
/* ComboBox item */
"open": _("WEP - Open"),
/* ComboBox item */
"sharedkey": _("WEP - Shared Key"),
/* ComboBox item */
// Ask me what it means, I don't know yet
"wpa-psk": _("WPA-PSK (WPA version 1 or 2)"),
/* ComboBox item */
"wpa-eap": _("WPA-EAP (WPA version 1 or 2)"),
];
map <string, string> ids = $["wpa-psk": "psk", "wpa-eap": "eap"];
if (authmodes == nil)
{
authmodes = (list<string>)Map::Keys (names);
}
else
{
// keep only those that we know how to handle
authmodes = filter (string am, authmodes, ``( haskey (names, am) ));
}
return maplist (string am, authmodes, ``( `item (`id (ids[am]:am), names[am]:am) ));
}
/**
* Wireless devices configuration dialog
* @return dialog result
*/
define any WirelessDialog() ``{
ScreenName("lan-hardware-wireless");
/* Wireless dialog caption */
string caption = _("Wireless Network Card Configuration");
string mode = LanItems::wl_mode;
string essid = LanItems::wl_essid;
string authmode = LanItems::wl_auth_mode;
// wpa or wep?
boolean authmode_wpa = authmode == "psk" || authmode == "eap"; // shortcut
string key = nil;
string type = nil;
if (authmode == "psk")
{
key = LanItems::wl_wpa_psk;
type = (size (key) == 64)? "hex": "passphrase";
}
else if (authmode != "eap")
{
map<string, string> wkey = ParseWepKey (LanItems::wl_key[LanItems::wl_default_key]:"");
key = wkey["key"]:"";
type = wkey["type"]:"";
}
else
{
key = ""; // and type is not used
}
list<integer> key_lengths = ParseKeyLengths (LanItems::wl_enc_modes);
/* Wireless dialog contents */
term contents = `HBox(
`HSpacing(4),
`VBox(
`VSpacing(0.5),
/* Frame label */
`Frame(_("Wireless Device Settings"), `HBox(`HSpacing(2), `VBox(
`VSpacing(0.5),
/* ComboBox label */
`ComboBox(`id(`mode), `opt(`hstretch), _("O&perating Mode"), [
/* ComboBox item */
`item(`id("Ad-hoc"), _("Ad-Hoc"), mode == "Ad-hoc"),
/* ComboBox item */
`item(`id("Managed"), _("Managed"), mode == "Managed"),
/* ComboBox item */
`item(`id("Master"), _("Master"), mode == "Master")
]),
`VSpacing(0.2),
/* Text entry label */
`HBox(
`ComboBox(`id(`essid), `opt(`editable), _("Ne&twork Name (ESSID)"), [ essid ]),
`PushButton(`id(`scan_for_networks), _("Scan Network"))
),
`VSpacing(0.2),
`ComboBox (`id (`authmode), `opt (`hstretch, `notify),
/* ComboBox label */
_("&Authentication Mode"),
AuthModeItems (LanItems::wl_auth_modes)),
`VSpacing(0.2),
type_w,
`VSpacing(0.2),
/* Text entry label */
`Password(`id(`key), _("&Encryption Key"), key),
`VSpacing(0.5)
), `HSpacing(2))),
`VSpacing(0.5),
`HBox(
/* PushButton label */
`PushButton(`id(`expert), _("E&xpert Settings")),
`HSpacing(0.5),
/* PushButton label, keys for WEP encryption */
`PushButton (`id(`keys), _("&WEP Keys"))
),
`VSpacing(0.5)
),
`HSpacing(4)
);
Wizard::SetContentsButtons(caption, contents, sformat("%1%2%3", help["wireless"]:"", help["wep_key"]:"", help["wpa"]:""),
Label::BackButton(), Label::NextButton());
// workaround for #118157
string no_apos = deletechars (String::CPrint (), "'");
UI::ChangeWidget (`id (`essid), `ValidChars, no_apos);
UI::ChangeWidget (`id (`authmode), `Value, authmode);
if (authmode != "eap")
{
UI::ChangeWidget (`id (`type_g), `CurrentButton, type);
}
string ckey = nil;
any ret = nil;
while(true) {
if (authmode_wpa)
{
UI::ChangeWidget (`id (`mode), `Value, "Managed");
}
UI::ChangeWidget (`id (`type_g), `Enabled, authmode!="no-encryption" && authmode!="eap");
UI::ChangeWidget (`id (`key), `Enabled, authmode!="no-encryption" && authmode!="eap");
UI::ChangeWidget (`id (`keys), `Enabled, authmode!="no-encryption" && !authmode_wpa);
UI::ChangeWidget (`id ("ascii"), `Enabled, authmode!="no-encryption" && authmode!="psk");
ret = UI::UserInput();
authmode = (string) UI::QueryWidget (`id (`authmode), `Value);
authmode_wpa = authmode == "psk" || authmode == "eap"; // shortcut
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back) {
break;
}
else if(ret == `next || ret == `expert || ret == `keys) {
mode = (string) UI::QueryWidget (`id (`mode), `Value);
// WPA-PSK and WPA-EAP are only allowed for Managed mode
if (authmode_wpa && mode != "Managed")
{
UI::SetFocus (`id (`mode));
/* Popup text */
Popup::Error (_("WPA authentication mode is only possible in managed operating mode."));
continue;
}
essid = (string) UI::QueryWidget (`id (`essid), `Value);
if (essid == "" && (mode != "Managed" || authmode_wpa))
{
UI::SetFocus (`id (`essid));
/* Popup text */
/* modes: combination of operation and authentication */
Popup::Error (_("Specify the network name for this mode."));
continue;
}
if (size(essid) > 32) {
UI::SetFocus (`id (`essid));
/* Popup text */
Popup::Error(_("The network name must be shorter than 32 characters."));
continue;
}
if (authmode!="no-encryption" && authmode!="eap") key = (string) UI::QueryWidget (`id (`key), `Value);
else {
key="";
LanItems::wl_key[LanItems::wl_default_key] = "";
LanItems::wl_wpa_psk = "";
}
type = (string) UI::QueryWidget (`id (`type_g), `CurrentButton);
if (authmode == "psk")
{
integer sz = size (key);
if (type == "passphrase" &&
(sz < 8 || sz > 63))
{
UI::SetFocus(`id(`key));
// Error popup
Popup::Error(_("The passphrase must have between 8 and 63 characters (inclusively)."));
continue;
}
else if (type == "hex" && !regexpmatch (key, "^[0-9A-Fa-f]{64}$"))
{
UI::SetFocus(`id(`key));
// Error popup
Popup::Error(sformat (_("The key must have %1 hexadecimal digits."), 64));
continue;
}
}
else if (!authmode_wpa)
{
ckey = ComposeWepKey (type, key);
if (ckey != "") {
if (!CheckWirelessKey (ckey, key_lengths))
{
UI::SetFocus(`id(`key));
/* Popup text */
Popup::Error(_("The encryption key is invalid."));
continue;
}
}
else {
UI::SetFocus(`id(`key));
if (authmode == "sharedkey") // error
{
/* Popup text */
Popup::Error (_("The encryption key must be specified for this authentication mode."));
continue;
}
else if (ret != `keys) // warning only
{
/* Popup text */
string pop = _("Using no encryption is a security risk.
Really continue?
");
if(!Popup::YesNo(pop)) {
continue;
}
}
}
}
break;
}
else if (ret == `scan_for_networks){
string command = sformat("ip link set %1 up && iwlist %1 scan|grep ESSID|cut -d':' -f2|cut -d'\"' -f2|sort -u", LanItems::Items[LanItems::current, "ifcfg"]:"");
map output = (map<string, any>)SCR::Execute(.target.bash_output, command);
if (output["exit"]:-1==0){
list<string> networks = splitstring(output["stdout"]:"", "\n");
y2milestone("Found networks : %1", networks);
UI::ChangeWidget(`essid, `Items, networks);
}
}
else if (ret != `authmode)
{
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next || ret == `expert || ret == `keys) {
LanItems::wl_essid = (string) UI::QueryWidget(`id(`essid), `Value);
LanItems::wl_mode = mode;
LanItems::wl_auth_mode = authmode;
if (authmode == "psk")
{
LanItems::wl_wpa_psk = key;
LanItems::wl_key[LanItems::wl_default_key] = "";
}
else if (!authmode_wpa && authmode!="no-encryption")
{
LanItems::wl_key[LanItems::wl_default_key] = ckey;
LanItems::wl_wpa_psk = "";
}
}
if (ret == `next && authmode == "eap")
{
ret = `eap; // continue by the WPA-EAP dialog
}
return ret;
}
/**
* Wireless expert configuration dialog
* @return dialog result
*/
define any WirelessExpertDialog() ``{
ScreenName("lan-hardware-wireless-expert");
/* Wireless expert dialog caption */
string caption = _("Wireless Expert Settings");
/* Wireless expert dialog help 1/5 */
string helptext = _("<p>Here, set additional configuration parameters
(rarely needed).</p>") +
/* Wireless expert dialog help 2/5 */
_("<p>To use your wireless LAN card in master or ad-hoc mode,
set the <b>Channel</b> the card should use here. This is not needed
for managed mode--the card will hop through the channels searching for access
points in that case.</p>
") +
/* Wireless expert dialog help 3/5 */
_("<p>In some rare cases, you may want to set a transmission
<b>Bit Rate</b> explicitly. The default is to go as fast as possible.</p>") +
/* Wireless expert dialog help 4/5 */
_("<p>In an environment with multiple <b>Access Points</b>, you may want to
define the one to which to connect by entering its MAC address.</p>") +
/* Wireless expert dialog help 5/5 */
_("<p><b>Use Power Management</b> enables power saving mechanisms.
This is generally a good idea, especially if you are a laptop user and may
be disconnected from AC power.</p>
");
string helpunused =
/* Wireless expert dialog help 2b/5 */
_("<p>To specify the <b>Frequency</b> instead of
the channel, select the desired value.</p>
");
/* Combobox label */
term freq = `ComboBox(`id(`frequency), `opt(`hstretch), _("&Frequency"), [
/* Combobox item */
`item(`id("Automatic"), _("Automatic"), LanItems::wl_frequency == ""),
`item(`id("Automatic"), "FIXME: ASK jg@suse.de", LanItems::wl_frequency != ""),
]);
list channels = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", ];
if (LanItems::wl_channels != nil)
{
channels = LanItems::wl_channels;
}
if(LanItems::wl_channel != "" && !contains(channels, LanItems::wl_channel))
channels = prepend(channels, LanItems::wl_channel);
/* Combobox item */
channels = prepend(channels, `item(`id(""), _("Automatic")));
list bitrates = [ "54", "48", "36", "24", "18", "12", "11", "9", "6", "5.5", "2", "1" ];
if (LanItems::wl_bitrates != nil)
{
bitrates = LanItems::wl_bitrates;
}
if(LanItems::wl_bitrate != "" && !contains(bitrates, LanItems::wl_bitrate))
bitrates = prepend(bitrates, LanItems::wl_bitrate);
/* Combobox item */
bitrates = prepend(bitrates, `item(`id(""), _("Automatic")));
/* Wireless expert dialog contents */
term contents = `HBox(
`HSpacing(4),
`VBox(
`VSpacing(0.5),
/* Frame label */
`Frame(_("Wireless Expert Settings"), `HBox(`HSpacing(2), `VBox(
`VSpacing(1),
/* Combobox label */
`ComboBox(`id(`channel), `opt(`hstretch), _("&Channel"), channels),
`VSpacing(0.2),
/* Combobox label */
`ComboBox(`id(`bitrate), `opt(`hstretch), _("B&it Rate"), bitrates),
`VSpacing(0.2),
/* Text entry label */
`InputField(`id(`accesspoint), `opt(`hstretch), _("&Access Point"), LanItems::wl_accesspoint),
`VSpacing(0.2),
/* CheckBox label */
`Left(`CheckBox(`id(`power), _("Use &Power Management"), LanItems::wl_power == true)),
`VSpacing(0.2),
`Left(`IntField(`id(`ap_scanmode), `opt(`hstretch), _("AP ScanMode"), 0,2,tointeger(LanItems::wl_ap_scanmode))),
`VSpacing(1)
), `HSpacing(2))),
`VSpacing(0.5)
),
`HSpacing(4)
);
Wizard::SetContentsButtons(caption, contents, helptext,
Label::BackButton(), Label::OKButton());
UI::ChangeWidget(`id(`bitrate), `Value, LanItems::wl_bitrate);
UI::ChangeWidget(`id(`channel), `Value, LanItems::wl_channel);
// #88530
boolean channel_changeable = contains (["Ad-hoc", "Master"], LanItems::wl_mode);
UI::ChangeWidget (`id (`channel), `Enabled, channel_changeable);
any ret = nil;
while(true) {
ret = UI::UserInput();
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back) {
break;
}
else if(ret == `next) {
/* Check */
break;
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next) {
LanItems::wl_channel = (string) UI::QueryWidget(`id(`channel), `Value);
// LanItems::wl_frequency = (string) UI::QueryWidget(`id(`frequency), `Value);
LanItems::wl_bitrate = (string) UI::QueryWidget(`id(`bitrate), `Value);
LanItems::wl_accesspoint = (string) UI::QueryWidget(`id(`accesspoint), `Value);
LanItems::wl_power = (boolean) UI::QueryWidget(`id(`power), `Value) == true;
LanItems::wl_ap_scanmode = tostring(UI::QueryWidget(`id(`ap_scanmode), `Value));
}
return ret;
}
/**
* Used to add or edit a key
* @param tkey has s: for ascii or h: for passphrase
* @param lengths allowed real key lengths
*/
define string WirelessKeyPopup (string tkey, list<integer> lengths) ``{
ScreenName("lan-hardware-wireless-key");
map<string, string> wkey = ParseWepKey (tkey);
string key = wkey["key"]:"";
string type = wkey["type"]:"";
term contents =
`HBox(
`HSpacing(1),
`VBox(
`VSpacing(0.2),
// Translators: popup dialog heading
`Heading (_("Enter Encryption Key")),
type_w, // common with the main dialog
`VSpacing(0.5),
// Translators: text entry label
`Left (`TextEntry (`id (`key), _("&Key"), key)),
`VSpacing(0.2),
`HBox (`PushButton (`id (`ok), `opt (`default, `key_F10),
Label::OKButton ()),
`PushButton (`id (`cancel), `opt (`key_F9),
Label::CancelButton ()),
`PushButton (`id (`help), `opt (`key_F1),
Label::HelpButton ())
),
`VSpacing(0.2)
),
`HSpacing(1)
);
UI::OpenDialog (`opt(`decorated), contents);
UI::ChangeWidget (`id (`type_g), `CurrentButton, type);
UI::SetFocus (`id (`key));
any ret = nil;
string ckey = nil;
while (true)
{
ret = UI::UserInput ();
if (ret == `help)
{
// Translators: popup title
Popup::LongText (_("Help"), `RichText (help["wep_key"]:""), 50, 18);
}
else if (ret == `cancel)
{
break;
}
else if (ret == `ok)
{
key = (string) UI::QueryWidget (`id (`key), `Value);
type = (string) UI::QueryWidget (`id (`type_g), `CurrentButton);
ckey = ComposeWepKey (type, key);
if (CheckWirelessKey (ckey, lengths))
{
break;
}
UI::SetFocus(`id(`key));
/* Popup text */
Popup::Error(_("The encryption key is invalid."));
}
else
{
y2error("Unexpected return code: %1", ret);
}
}
if (ret == `ok)
{
tkey = ckey;
}
UI::CloseDialog ();
return tkey;
}
/**
* Generate items for the keys table
*/
define list<term> WirelessKeysItems (list<string> keys, integer defaultk) ``{
return maplist (integer i, [0, 1, 2, 3],
``( `item (`id (i), i, keys[i]:"", (i==defaultk)? "*":"") )
);
}
/**
* In case the current default key is empty, find a nonempty one
* or the first one.
*/
define integer FindGoodDefault (list<string> keys, integer defaultk) ``{
if (keys[defaultk]:"" != "")
{
return defaultk;
}
defaultk = find (integer i, [0, 1, 2, 3], ``( keys[i]:"" != "" ));
if (defaultk == nil)
{
defaultk = 0;
}
return defaultk;
}
/**
* Wireless expert configuration dialog
* @return dialog result
*/
define any WirelessKeysDialog() ``{
ScreenName("lan-hardware-wireless-keys");
/* Wireless keys dialog caption */
string caption = _("Wireless Keys");
/* Wireless keys dialog help 1/3 */
string helptext = _("<p>In this dialog, define your WEP keys used
to encrypt your data before it is transmitted. You can have up to four keys,
although only one key is used to encrypt the data. This is the default key.
The other keys can be used to decrypt data. Usually you have only
one key.</p>") +
/* Wireless keys dialog help 2/3 */
_("<p><b>Key Length</b> defines the bit length of your WEP keys.
Possible are 64 and 128 bit, sometimes also referred to as 40 and 104 bit.
Some older hardware might not be able to handle 128 bit keys, so if your
wireless LAN connection does not establish, you may need to set this
value to 64.</p>") +
"";
string length = LanItems::wl_key_length;
list<string> ui_key_lengths = maplist (integer kl,
ParseKeyLengths (LanItems::wl_enc_modes),
``( tostring (kl + 24) ));
if (!contains (ui_key_lengths, length))
{
ui_key_lengths = add (ui_key_lengths, length);
}
list<string> keys = LanItems::wl_key;
integer defaultk = FindGoodDefault (keys, LanItems::wl_default_key);
/* Wireless keys dialog contents */
term contents = `HBox(
`HSpacing(5),
`VBox(
`VSpacing(1),
/* Frame label */
`Frame(_("WEP Keys"), `HBox(`HSpacing(3), `VBox(
`VSpacing(1),
/* ComboBox label */
`Left(`ComboBox(`id(`length), _("&Key Length"), ui_key_lengths)),
`VSpacing(1),
`Table(`id(`table), `opt(`notify),
`header(
/* Table header label */
// Abbreviation of Number
_("No."),
/* Table header label */
_("Key"),
/* Table header label */
`Center (_("Default"))),
WirelessKeysItems (keys, defaultk)),
`HBox(
/* PushButton label */
`PushButton(`id(`edit), Label::EditButton()),
/* PushButton label */
`PushButton(`id(`delete), Label::DeleteButton()),
/* PushButton label */
`PushButton(`id(`default), _("&Set as Default"))),
`VSpacing(1)
), `HSpacing(3))),
`VSpacing(1)
),
`HSpacing(5)
);
Wizard::SetContentsButtons(caption, contents, helptext,
Label::BackButton(), Label::OKButton());
UI::ChangeWidget (`id (`length), `Value, length);
integer current = (integer) UI::QueryWidget (`id (`table), `CurrentItem);
any ret = nil;
while(true) {
foreach (symbol btn, [`edit, `delete, `default], ``{
UI::ChangeWidget (`id (btn), `Enabled, current != nil);
});
UI::SetFocus (`id (`table));
ret = UI::UserInput();
current = (integer) UI::QueryWidget (`id (`table), `CurrentItem);
length = (string) UI::QueryWidget (`id (`length), `Value);
integer rlength = tointeger (length) - 24;
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `table || ret == `edit || ret == `delete) {
keys[current] = (ret != `delete) ? WirelessKeyPopup (keys[current]:"", [rlength]) : "";
defaultk = FindGoodDefault (keys, defaultk);
UI::ChangeWidget (`id (`table), `Items, WirelessKeysItems (keys, defaultk));
}
else if(ret == `default) {
defaultk = FindGoodDefault (keys, current);
UI::ChangeWidget (`id (`table), `Items, WirelessKeysItems (keys, defaultk));
}
else if(ret == `next || ret == `back) {
break;
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next) {
LanItems::wl_key_length = length;
LanItems::wl_key = keys;
LanItems::wl_default_key = defaultk;
}
return ret;
}
// -------------------- WPA EAP --------------------
/**
* function to initialize widgets
* @param key widget id
*/
define void InitializeWidget (string key) {
// the "" serves instead of a default constructor for wl_wpa_eap
any value = LanItems::wl_wpa_eap[key]:"";
my2debug ("AW", sformat ("init k: %1, v: %2", key, value));
UI::ChangeWidget (`id (key), ValueProp (key), value);
}
/**
* function to store data from widget
* @param key widget id
* @param event ?
*/
define void StoreWidget (string key, map event) {
any value = UI::QueryWidget (`id (key), ValueProp (key));
my2debug ("AW", sformat ("store k: %1, v: %2, e: %3", key, value, event));
LanItems::wl_wpa_eap[key] = value;
}
/**
* Event handler for EAP mode:
* enable or disable appropriate widgets
* @param key the widget receiving the event
* @param event the event being handled
* @return nil so that the dialog loops on
*/
define symbol HandleEapMode (string key, map event) {
// my2debug ("HSI", sformat ("k: %1 e: %2", key, event));
boolean tls = UI::QueryWidget (`id (key), `Value) == "TLS";
foreach (string id, ["WPA_EAP_PASSWORD",
"WPA_EAP_ANONID",
"DETAILS_B",
], {
UI::ChangeWidget (`id (id), `Enabled, !tls);
});
foreach (string id, ["WPA_EAP_CLIENT_CERT",
"WPA_EAP_CLIENT_CERT_BROWSE",
"WPA_EAP_CLIENT_KEY",
"WPA_EAP_CLIENT_KEY_BROWSE",
"WPA_EAP_CLIENT_KEY_PASSWORD",
], {
UI::ChangeWidget (`id (id), `Enabled, tls);
});
return nil;
}
/**
* function to initialize widgets
* @param key widget id
*/
define void InitEapMode (string key) {
// inherited
InitializeWidget (key);
// enable/disable
HandleEapMode (key, $["ID": "_cwm_wakeup"]);
}
/**
* function to initialize widgets
* @param key widget id
*/
define void InitPeapVersion (string key) {
// inherited
InitializeWidget (key);
// enable/disable
string mode = LanItems::wl_wpa_eap["WPA_EAP_MODE"]:"";
UI::ChangeWidget (`id (key), `Enabled, mode == "peap");
}
/**
* Called when one of the two file browser buttons is pressed
* @param key widget id
* @param event ?
* @return nil so that the dialog does not exit
*/
define symbol HandleFileBrowse (string key, map event) {
// only process our own events
if (event["ID"]:nil != key)
{
return nil;
}
/* convert to the text entry widget we belong to */
map attached_to = $[
"WPA_EAP_CLIENT_CERT_BROWSE": "WPA_EAP_CLIENT_CERT",
"WPA_EAP_CLIENT_KEY_BROWSE": "WPA_EAP_CLIENT_KEY",
"WPA_EAP_CA_CERT_BROWSE": "WPA_EAP_CA_CERT",
];
key = attached_to[key]:"";
/* get the file and its directory if already entered*/
string file = (string) UI::QueryWidget (`id (key), `Value);
integer slashpos = findlastof (file, "/");
string defaultd = "."; // "/etc/cert";
string dir = slashpos == nil ? defaultd : substring (file, 0, slashpos);
// file browser dialog headline
file = UI::AskForExistingFile (dir, "*", _("Choose a Certificate"));
if (file != nil) {
// fill the value
UI::ChangeWidget (`id (key), `Value, file);
}
return nil;
}
/**
* Remap the buttons to their Wizard Sequencer values
* @param key the widget receiving the event
* @param event the event being handled
* @return nil so that the dialog loops on
*/
define symbol HandleDetails (string key, map event) {
if (event["ID"]:nil == "DETAILS_B")
return `details;
return nil;
}
/**
* Called to validate that the file entered exists
* @param key widget id
* @param event ?
* @return ok?
*/
define boolean ValidateFileExists (string key, map event) {
string file = (string) UI::QueryWidget (`id (key), `Value);
if (file == "")
{
return true; // validated in ValidateWpaEap
}
if (FileUtils::Exists (file))
{
return true;
}
else
{
UI::SetFocus (`id (key));
Popup::Error (Message::CannotOpenFile (file));
return false;
}
}
define boolean ValidateCaCertExists (string key, map event) {
boolean ret=true;
if (size((string) UI::QueryWidget (`id (key), `Value))==0 || !ValidateFileExists(key, event)){
if (!Popup::YesNo(_("Not using a Certificate Authority (CA) certificate can result in connections
to insecure, rogue wireless networks. Continue without CA ?"))) ret=false;
}
return ret;
}
/**
* Called to validate that the whole dialog makes sense together
* @param key widget id
* @param event ?
* @return ok?
*/
define boolean ValidateWpaEap (string key, map event) {
map tmp = listmap (string key, [
"WPA_EAP_IDENTITY",
//"WPA_EAP_PASSWORD",
"WPA_EAP_CLIENT_CERT",
],
``( $[ key: UI::QueryWidget (`id (key), `Value) ] ));
if (tmp["WPA_EAP_CLIENT_CERT"]:"" == "" && tmp["WPA_EAP_IDENTITY"]:"" =="")
{
UI::SetFocus (`id ("WPA_EAP_IDENTITY"));
// error popup text
Popup::Error (_("Enter either the identity and password
or the client certificate."));
return false;
}
else
{
return true;
}
}
map<string, map<string,any> > wpa_eap_widget_descr = $[
"WPA_EAP_MODE": $[
"widget": `combobox,
// combo box label
"label": _("EAP &Mode"),
"opt": [`notify],
"items": [
// combo box item, one of WPA EAP modes
["TTLS", _("TTLS")],
// combo box item, one of WPA EAP modes
["PEAP", _("PEAP")],
// combo box item, one of WPA EAP modes
["TLS", _("TLS")],
],
"help": _("<p>WPA-EAP uses a RADIUS server to authenticate users. There
are different methods in EAP to connect to the server and
perform the authentication, namely TLS, TTLS, and PEAP.</p>
"),
"init": InitEapMode,
"handle": HandleEapMode,
],
// the four WPA_EAP_* widgets come together, so the helps are
// dipersed a bit
"WPA_EAP_IDENTITY": $[
"widget": `textentry,
// text entry label
"label": _("&Identity"),
"opt": [],
"help": _("<p>For TTLS and PEAP, enter your <b>Identity</b>
and <b>Password</b> as configured on the server.
If you have special requirements to set the username used as
<b>Anonymous Identity</b>, you may set it here. This is usually not needed.</p>
"),
],
"WPA_EAP_ANONID": $[
"widget": `textentry,
// text entry label
"label": _("&Anonymous Identity"),
"opt": [],
"help": "",
],
"WPA_EAP_PASSWORD": $[
"widget": `password, // or password?
// text entry label
"label": _("&Password"),
"opt": [],
"help": "",
],
"WPA_EAP_CLIENT_CERT": $[
"widget": `textentry,
// text entry label
"label": _("&Client Certificate"),
"opt": [],
"help": _("<p>TLS uses a <b>Client Certificate</b> instead of a username and
password combination for authentication. It uses a public and private key pair
to encrypt negotiation communication, therefore you will additionally need
a <b>Client Key</b> file that contains your private key and
the appropriate <b>Client Key Password</b> for that file.</p>
"),
"validate_type": `function,
"validate_function": ValidateFileExists,
],
"WPA_EAP_CLIENT_KEY": $[
"widget": `textentry,
// text entry label
"label": _("Client &Key"),
"opt": [],
"help": "",
"validate_type": `function,
"validate_function": ValidateFileExists,
],
"WPA_EAP_CLIENT_KEY_PASSWORD": $[
"widget": `textentry, // or password?
// text entry label
"label": _("Client Key Pass&word"),
"opt": [],
"help": "",
],
"WPA_EAP_CA_CERT": $[
"widget": `textentry,
// text entry label
// aka certificate of the CA (certification authority)
"label": _("&Server Certificate"),
"opt": [],
"help": _("<p>To increase security, it is recommended to configure
a <b>Server Certificate</b>. It is used
to validate the server's authenticity.</p>
"),
"validate_type": `function,
"validate_function": ValidateCaCertExists,
],
"WPA_EAP_CLIENT_CERT_BROWSE": $[
"widget": `push_button,
"label": "...",
"opt": [`autoShortcut],
"help": "",
"init": CWM::InitNull,
"store": CWM::StoreNull,
"handle": HandleFileBrowse,
],
"WPA_EAP_CLIENT_KEY_BROWSE": $[
"widget": `push_button,
"label": "...",
"opt": [`autoShortcut],
"help": "",
"init": CWM::InitNull,
"store": CWM::StoreNull,
"handle": HandleFileBrowse,
],
"WPA_EAP_CA_CERT_BROWSE": $[
"widget": `push_button,
"label": "...",
"opt": [`autoShortcut],
"help": "",
"init": CWM::InitNull,
"store": CWM::StoreNull,
"handle": HandleFileBrowse,
],
"DETAILS_B": $[
"widget": `push_button,
// push button label
"label": _("&Details"),
"opt": [],
"help": "",
"init": CWM::InitNull,
"store": CWM::StoreNull,
"handle": HandleDetails,
],
"WPA_EAP_DUMMY": $[
"widget": `empty,
"help": _("If you do not know your ID and password or you do not have
any certificate or key files, contact your system administrator.
"),
"init": CWM::InitNull,
"store": CWM::StoreNull,
"validate_type": `function,
"validate_function": ValidateWpaEap,
],
// Details dialog
"WPA_EAP_AUTH": $[
"widget": `combobox,
// combo box label
"label": _("&Authentication Method"),
"help":
_("<p>Here you can configure the inner authentication (also known as phase 2)
method. By default, all methods are allowed. If you want to restrict the
allowed methods or in case you have encountered difficulties regarding
authentication, choose your inner authentication method.</p>
"),
],
"WPA_EAP_PEAP_VERSION": $[
"widget": `radio_buttons,
// radio button group label
"label": _("&PEAP Version"),
"help":
_("<p>If you are using PEAP, you can also force the use of a specific PEAP
implementation (version 0 or 1). Normally this should not be necessary.</p>
"),
"items": [
// radio button: any version of PEAP
["", _("&Any")],
["0", "&0"],
["1", "&1"],
],
"init": InitPeapVersion,
],
];
/**
* Lays out a text entry and a push button, with proper alignment
*/
define term AddButton (string id, string button_id) {
// return `HBox (id, button_id);
// needs new CWM
return (
`VSquash ( // only for old UI?
`HBox (
id, `Bottom (button_id)
)
)
);
}
/**
* Settings for WPA-EAP
* @return dialog result
*/
define any WirelessWpaEapDialog () {
term contents = `VBox (
"WPA_EAP_MODE",
"WPA_EAP_DUMMY",
`HBox (
"WPA_EAP_IDENTITY",
`HSpacing (1),
"WPA_EAP_PASSWORD"
),
"WPA_EAP_ANONID",
AddButton ("WPA_EAP_CLIENT_CERT", "WPA_EAP_CLIENT_CERT_BROWSE"),
`HBox (
AddButton ("WPA_EAP_CLIENT_KEY", "WPA_EAP_CLIENT_KEY_BROWSE"),
`HSpacing (1),
"WPA_EAP_CLIENT_KEY_PASSWORD"
),
AddButton ("WPA_EAP_CA_CERT", "WPA_EAP_CA_CERT_BROWSE"),
`VSpacing (1),
`Right ("DETAILS_B")
);
map functions = $[
"init" : InitializeWidget,
"store" : StoreWidget,
`abort: ReallyAbort, // undocumented, FIXME
];
return CWM::ShowAndRun (
$[
"widget_descr": wpa_eap_widget_descr,
"contents": contents,
// dialog caption
"caption": _("WPA-EAP"),
"back_button" : Label::BackButton (),
"next_button" : Label::NextButton (),
"fallback_functions" : functions,
]);
}
/**
* Detailed settings for WPA-EAP
* @return dialog result
*/
define any WirelessWpaEapDetailsDialog () {
term contents = `HSquash (`VBox (
"WPA_EAP_AUTH",
`VSpacing (1),
"WPA_EAP_PEAP_VERSION"
));
map functions = $[
"init" : InitializeWidget,
"store" : StoreWidget,
`abort: ReallyAbort,
];
map<string, string> auth_names = $[
// combo box item, any of EAP authentication methods
"": _("Any"),
// combo box item, an EAP authentication method
"MD5": _("MD5"),
// combo box item, an EAP authentication method
"GTC": _("GTC"),
// combo box item, an EAP authentication method
"CHAP": _("CHAP"),
// combo box item, an EAP authentication method
"PAP": _("PAP"),
// combo box item, an EAP authentication method
"MSCHAP": _("MSCHAPv1"),
// combo box item, an EAP authentication method
"MSCHAPV2": _("MSCHAPv2"),
];
map<string, list<string> > auth_items = $[
"TTLS": ["", "MD5", "GTC", "CHAP", "PAP", "MSCHAP", "MSCHAPV2"],
"PEAP": ["", "MD5", "GTC", "MSCHAPV2"],
];
string mode = LanItems::wl_wpa_eap["WPA_EAP_MODE"]:"";
map<string, map<string,any> > wd = wpa_eap_widget_descr;
wd["WPA_EAP_AUTH", "items"] = maplist (string i, auth_items[mode]:[],
``( [i, auth_names[i]:""] ));
return CWM::ShowAndRun (
$[
"widget_descr": wd,
"contents": contents,
// dialog caption
"caption": _("WPA-EAP Details"),
"back_button" : Label::BackButton (),
"next_button" : Label::OKButton (),
"fallback_functions" : functions,
]);
}
/* EOF */
}
ACC SHELL 2018