Commit 85b6b659 authored by Beniamino Galvani's avatar Beniamino Galvani

editor: improve the cloned MAC address selection

Add a combo box with text entry that accepts a MAC address and also
the selection of one of the predefined special values.

It is not possible to configure properties like the generated MAC
address mask or the stable id. For these advanced settings users
should rely on nmcli.
parent 1524f5e4
......@@ -168,10 +168,16 @@
</packing>
</child>
<child>
<object class="GtkEntry" id="ethernet_cloned_mac">
<object class="GtkComboBoxText" id="ethernet_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The MAC address entered here will be used as hardware address for the network device this connection is activated on. This feature is known as MAC cloning or spoofing. Example: 00:11:22:33:44:55</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="active_id">0</property>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
......
......@@ -65,11 +65,16 @@
</packing>
</child>
<child>
<object class="GtkEntry" id="vlan_cloned_mac_entry">
<object class="GtkComboBoxText" id="vlan_cloned_mac_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char"></property>
<property name="invisible_char_set">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="active_id">0</property>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
......
......@@ -152,10 +152,16 @@
</packing>
</child>
<child>
<object class="GtkEntry" id="wifi_cloned_mac">
<object class="GtkComboBoxText" id="wifi_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The MAC address entered here will be used as hardware address for the network device this connection is activated on. This feature is known as MAC cloning or spoofing. Example: 00:11:22:33:44:55</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="active_id">0</property>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
......
......@@ -287,14 +287,53 @@ ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
_set_active_combo_item (combo, mac, active_mac, active_idx);
}
gboolean
ce_page_mac_entry_valid (GtkEntry *entry, int type, const char *property_name, GError **error)
void
ce_page_setup_cloned_mac_combo (GtkComboBoxText *combo, const char *current)
{
const char *mac;
GtkWidget *entry;
static const char *entries[][2] = { { "preserve", N_("Preserve") },
{ "permanent", N_("Permanent") },
{ "random", N_("Random") },
{ "stable", N_("Stable") } };
int i, active = -1;
gtk_widget_set_tooltip_text (GTK_WIDGET (combo),
_("The MAC address entered here will be used as hardware address for "
"the network device this connection is activated on. This feature is "
"known as MAC cloning or spoofing. Example: 00:11:22:33:44:55"));
gtk_combo_box_text_remove_all (combo);
for (i = 0; i < G_N_ELEMENTS (entries); i++) {
gtk_combo_box_text_append (combo, entries[i][0], _(entries[i][1]));
if (nm_streq0 (current, entries[i][0]))
active = i;
}
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
if (active != -1) {
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
} else if (current && current[0]) {
entry = gtk_bin_get_child (GTK_BIN (combo));
g_assert (entry);
gtk_entry_set_text (GTK_ENTRY (entry), current);
}
}
const char *
ce_page_cloned_mac_get (GtkComboBoxText *combo)
{
const char *id;
mac = gtk_entry_get_text (entry);
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo));
if (id)
return id;
return gtk_combo_box_text_get_active_text (combo);
}
static gboolean
mac_valid (const char *mac, int type, const char *property_name, GError **error)
{
if (mac && *mac) {
if (!nm_utils_hwaddr_valid (mac, nm_utils_hwaddr_len (type))) {
const char *addr_type;
......@@ -312,9 +351,30 @@ ce_page_mac_entry_valid (GtkEntry *entry, int type, const char *property_name, G
return FALSE;
}
}
return TRUE;
}
gboolean
ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo, int type, const char *property_name, GError **error)
{
if (gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) != -1)
return TRUE;
return mac_valid (gtk_combo_box_text_get_active_text (combo),
type,
property_name,
error);
}
gboolean
ce_page_mac_entry_valid (GtkEntry *entry, int type, const char *property_name, GError **error)
{
g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);
return mac_valid (gtk_entry_get_text (entry), type, property_name, error);
}
gboolean
ce_page_interface_name_valid (const char *iface, const char *property_name, GError **error)
{
......
......@@ -136,6 +136,7 @@ void ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
const char *mac, char **mac_list);
void ce_page_setup_data_combo (CEPage *self, GtkComboBox *combo,
const char *data, char **list);
void ce_page_setup_cloned_mac_combo (GtkComboBoxText *combo, const char *current);
void ce_page_setup_device_combo (CEPage *self,
GtkComboBox *combo,
GType device_type,
......@@ -149,6 +150,8 @@ gboolean ce_page_device_entry_get (GtkEntry *entry, int type,
char **ifname, char **mac,
const char *device_name,
GError **error);
const char *ce_page_cloned_mac_get (GtkComboBoxText *combo);
gboolean ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo, int type, const char *property_name, GError **error);
void ce_page_changed (CEPage *self);
......
......@@ -35,7 +35,7 @@ typedef struct {
NMSettingWired *setting;
GtkComboBoxText *device_combo; /* Device identification (ifname and/or MAC) */
GtkEntry *cloned_mac; /* Cloned MAC - used for MAC spoofing */
GtkComboBoxText *cloned_mac; /* Cloned MAC - used for MAC spoofing */
GtkComboBox *port;
GtkComboBox *speed;
GtkComboBox *duplex;
......@@ -91,7 +91,7 @@ ethernet_private_init (CEPageEthernet *self)
label = GTK_LABEL (gtk_builder_get_object (builder, "ethernet_device_label"));
gtk_label_set_mnemonic_widget (label, GTK_WIDGET (priv->device_combo));
priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "ethernet_cloned_mac"));
priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "ethernet_cloned_mac"));
priv->port = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ethernet_port"));
priv->speed = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ethernet_speed"));
priv->duplex = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ethernet_duplex"));
......@@ -249,8 +249,7 @@ populate_ui (CEPageEthernet *self)
/* Cloned MAC address */
s_mac = nm_setting_wired_get_cloned_mac_address (setting);
if (s_mac)
gtk_entry_set_text (priv->cloned_mac, s_mac);
ce_page_setup_cloned_mac_combo (priv->cloned_mac, s_mac);
g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);
/* MTU */
......@@ -454,7 +453,7 @@ ui_to_setting (CEPageEthernet *self)
entry = gtk_bin_get_child (GTK_BIN (priv->device_combo));
if (entry)
ce_page_device_entry_get (GTK_ENTRY (entry), ARPHRD_ETHER, TRUE, &ifname, &device_mac, NULL, NULL);
cloned_mac = gtk_entry_get_text (priv->cloned_mac);
cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
/* Wake-on-LAN */
if (gtk_toggle_button_get_active (priv->wol_default))
......@@ -516,7 +515,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
return FALSE;
}
if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
return FALSE;
if (gtk_widget_get_sensitive (GTK_WIDGET (priv->wol_passwd))) {
......
......@@ -52,7 +52,7 @@ typedef struct {
GtkEntry *parent_entry;
GtkSpinButton *id_entry;
GtkEntry *name_entry;
GtkEntry *cloned_mac;
GtkComboBoxText *cloned_mac;
GtkSpinButton *mtu;
GtkToggleButton *flag_reorder_hdr, *flag_gvrp, *flag_loose_binding, *flag_mvrp;
......@@ -84,7 +84,7 @@ vlan_private_init (CEPageVlan *self)
priv->id_entry = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_id_entry"));
priv->name_entry = GTK_ENTRY (gtk_builder_get_object (builder, "vlan_name_entry"));
priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "vlan_cloned_mac_entry"));
priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "vlan_cloned_mac_entry"));
priv->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_mtu"));
priv->flag_reorder_hdr = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "reorder_hdr_flag"));
priv->flag_gvrp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "gvrp_flag"));
......@@ -285,7 +285,7 @@ parent_changed (GtkWidget *widget, gpointer user_data)
gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), TRUE);
} else {
gtk_widget_set_sensitive (GTK_WIDGET (priv->cloned_mac), FALSE);
gtk_entry_set_text (priv->cloned_mac, "");
ce_page_setup_cloned_mac_combo (priv->cloned_mac, NULL);
gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), FALSE);
gtk_spin_button_set_value (priv->mtu, 1500);
}
......@@ -532,8 +532,9 @@ populate_ui (CEPageVlan *self)
/* Cloned MAC address */
if (NM_IS_SETTING_WIRED (priv->s_hw)) {
const char *mac = nm_setting_wired_get_cloned_mac_address (NM_SETTING_WIRED (priv->s_hw));
if (mac)
gtk_entry_set_text (priv->cloned_mac, mac);
ce_page_setup_cloned_mac_combo (priv->cloned_mac, mac);
} else {
ce_page_setup_cloned_mac_combo (priv->cloned_mac, NULL);
}
g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);
......@@ -693,7 +694,7 @@ ui_to_setting (CEPageVlan *self)
NULL);
if (hwtype != G_TYPE_NONE) {
cloned_mac = gtk_entry_get_text (priv->cloned_mac);
cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
if (cloned_mac && !*cloned_mac)
cloned_mac = NULL;
mtu_set = g_ascii_isdigit (*gtk_entry_get_text (GTK_ENTRY (priv->mtu)));
......@@ -737,7 +738,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
g_free (parent_iface);
}
if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
return FALSE;
ui_to_setting (self);
......
......@@ -38,7 +38,7 @@ typedef struct {
GtkEntry *ssid;
GtkComboBoxText *bssid;
GtkComboBoxText *device_combo; /* Device identification (ifname and/or MAC) */
GtkEntry *cloned_mac; /* Cloned MAC - used for MAC spoofing */
GtkComboBoxText *cloned_mac; /* Cloned MAC - used for MAC spoofing */
GtkComboBox *mode;
GtkComboBox *band;
GtkSpinButton *channel;
......@@ -65,7 +65,7 @@ wifi_private_init (CEPageWifi *self)
priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
priv->ssid = GTK_ENTRY (gtk_builder_get_object (builder, "wifi_ssid"));
priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "wifi_cloned_mac"));
priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "wifi_cloned_mac"));
priv->mode = GTK_COMBO_BOX (gtk_builder_get_object (builder, "wifi_mode"));
priv->band = GTK_COMBO_BOX (gtk_builder_get_object (builder, "wifi_band"));
priv->channel = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "wifi_channel"));
......@@ -387,8 +387,7 @@ populate_ui (CEPageWifi *self)
/* Cloned MAC address */
s_mac = nm_setting_wireless_get_cloned_mac_address (setting);
if (s_mac)
gtk_entry_set_text (priv->cloned_mac, s_mac);
ce_page_setup_cloned_mac_combo (priv->cloned_mac, s_mac);
g_signal_connect_swapped (priv->cloned_mac, "changed", G_CALLBACK (ce_page_changed), self);
gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting));
......@@ -528,7 +527,7 @@ ui_to_setting (CEPageWifi *self)
entry = gtk_bin_get_child (GTK_BIN (priv->device_combo));
if (entry)
ce_page_device_entry_get (GTK_ENTRY (entry), ARPHRD_ETHER, TRUE, &ifname, &device_mac, NULL, NULL);
cloned_mac = gtk_entry_get_text (priv->cloned_mac);
cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
......@@ -571,7 +570,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
return FALSE;
}
if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
return FALSE;
ui_to_setting (self);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment