network: Handle cloned-mac setting

This can be set to 'preserve', 'permanent', 'random' or 'stable'. We
need to handle these values otherwise we can end up with the editor
being un-saveable.

Turn the entry in to a GtkComboBoxText with those items in it, allowing
a mac address to be typed too.

Partial copy of 85b6b659a140a59c3df787062e089a0b4e2a547d from
network-manager-applet.
This commit is contained in:
Iain Lane 2019-04-24 16:16:09 +01:00 committed by Robert Ancell
parent 538cbfb4da
commit 566db3a35f
8 changed files with 104 additions and 28 deletions

View file

@ -65,7 +65,7 @@ connect_ethernet_page (CEPageEthernet *page)
/* Cloned MAC address */ /* Cloned MAC address */
cloned_mac = nm_setting_wired_get_cloned_mac_address (setting); cloned_mac = nm_setting_wired_get_cloned_mac_address (setting);
gtk_entry_set_text (GTK_ENTRY (page->cloned_mac), cloned_mac ? cloned_mac : ""); ce_page_setup_cloned_mac_combo (page->cloned_mac, cloned_mac);
g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page); g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page);
/* MTU */ /* MTU */
@ -89,6 +89,7 @@ ui_to_setting (CEPageEthernet *page)
gchar *cloned_mac = NULL; gchar *cloned_mac = NULL;
const gchar *text; const gchar *text;
GtkWidget *entry; GtkWidget *entry;
GtkComboBoxText *combo;
entry = gtk_bin_get_child (GTK_BIN (page->device_mac)); entry = gtk_bin_get_child (GTK_BIN (page->device_mac));
if (entry) { if (entry) {
@ -96,8 +97,8 @@ ui_to_setting (CEPageEthernet *page)
device_mac = ce_page_trim_address (text); device_mac = ce_page_trim_address (text);
} }
text = gtk_entry_get_text (GTK_ENTRY (page->cloned_mac)); combo = page->cloned_mac;
cloned_mac = ce_page_trim_address (text); cloned_mac = ce_page_cloned_mac_get (combo);
g_object_set (page->setting_wired, g_object_set (page->setting_wired,
NM_SETTING_WIRED_MAC_ADDRESS, device_mac, NM_SETTING_WIRED_MAC_ADDRESS, device_mac,
@ -120,6 +121,7 @@ validate (CEPage *page,
{ {
CEPageEthernet *self = CE_PAGE_ETHERNET (page); CEPageEthernet *self = CE_PAGE_ETHERNET (page);
GtkWidget *entry; GtkWidget *entry;
GtkComboBoxText *combo;
gboolean ret = TRUE; gboolean ret = TRUE;
entry = gtk_bin_get_child (GTK_BIN (self->device_mac)); entry = gtk_bin_get_child (GTK_BIN (self->device_mac));
@ -132,11 +134,12 @@ validate (CEPage *page,
} }
} }
if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (self->cloned_mac)))) { combo = self->cloned_mac;
widget_set_error (GTK_WIDGET (self->cloned_mac)); if (!ce_page_cloned_mac_combo_valid (combo)) {
widget_set_error (gtk_bin_get_child (GTK_BIN (combo)));
ret = FALSE; ret = FALSE;
} else { } else {
widget_unset_error (GTK_WIDGET (self->cloned_mac)); widget_unset_error (gtk_bin_get_child (GTK_BIN (combo)));
} }
if (!ret) if (!ret)
@ -175,7 +178,7 @@ ce_page_ethernet_new (NMConnection *connection,
page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name"));
page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"));
page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); page->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_cloned_mac"));
page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu")); page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu"));
page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu")); page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu"));

View file

@ -50,7 +50,7 @@ struct _CEPageEthernet
GtkEntry *name; GtkEntry *name;
GtkComboBoxText *device_mac; GtkComboBoxText *device_mac;
GtkEntry *cloned_mac; GtkComboBoxText *cloned_mac;
GtkSpinButton *mtu; GtkSpinButton *mtu;
GtkWidget *mtu_label; GtkWidget *mtu_label;
}; };

View file

@ -85,9 +85,9 @@ connect_wifi_page (CEPageWifi *page)
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"entry_cloned_mac")); "combo_cloned_mac"));
cloned_mac = nm_setting_wireless_get_cloned_mac_address (page->setting); cloned_mac = nm_setting_wireless_get_cloned_mac_address (page->setting);
gtk_entry_set_text (GTK_ENTRY (widget), cloned_mac ? cloned_mac : ""); ce_page_setup_cloned_mac_combo (GTK_COMBO_BOX_TEXT (widget), cloned_mac);
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
} }
@ -97,6 +97,7 @@ ui_to_setting (CEPageWifi *page)
GBytes *ssid; GBytes *ssid;
const gchar *utf8_ssid, *bssid; const gchar *utf8_ssid, *bssid;
GtkWidget *entry; GtkWidget *entry;
GtkComboBoxText *combo;
char *device_mac, *cloned_mac; char *device_mac, *cloned_mac;
entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid")); entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid"));
@ -112,8 +113,8 @@ ui_to_setting (CEPageWifi *page)
bssid = NULL; bssid = NULL;
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"))); entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")));
device_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); device_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry)));
entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); combo = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_cloned_mac"));
cloned_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); cloned_mac = ce_page_cloned_mac_get (combo);
g_object_set (page->setting, g_object_set (page->setting,
NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_SSID, ssid,
@ -134,6 +135,7 @@ validate (CEPage *page,
GError **error) GError **error)
{ {
GtkWidget *entry; GtkWidget *entry;
GtkComboBoxText *combo;
gboolean ret = TRUE; gboolean ret = TRUE;
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid"))); entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid")));
@ -152,12 +154,12 @@ validate (CEPage *page,
widget_unset_error (entry); widget_unset_error (entry);
} }
entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac")); combo = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (page->builder, "combo_cloned_mac"));
if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { if (!ce_page_cloned_mac_combo_valid (combo)) {
widget_set_error (entry); widget_set_error (gtk_bin_get_child (GTK_BIN (combo)));
ret = FALSE; ret = FALSE;
} else { } else {
widget_unset_error (entry); widget_unset_error (gtk_bin_get_child (GTK_BIN (combo)));
} }
if (!ret) if (!ret)

View file

@ -389,6 +389,50 @@ ce_page_trim_address (const gchar *addr)
return g_strdup (addr); return g_strdup (addr);
} }
void
ce_page_setup_cloned_mac_combo (GtkComboBoxText *combo, const char *current)
{
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 (g_strcmp0 (current, entries[i][0]) == 0)
active = i;
}
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);
}
}
char *
ce_page_cloned_mac_get (GtkComboBoxText *combo)
{
const char *id;
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo));
if (id)
return g_strdup (id);
return gtk_combo_box_text_get_active_text (combo);
}
gboolean gboolean
ce_page_address_is_valid (const gchar *addr) ce_page_address_is_valid (const gchar *addr)
{ {
@ -431,6 +475,19 @@ ce_page_address_is_valid (const gchar *addr)
return TRUE; return TRUE;
} }
gboolean
ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo)
{
g_autofree gchar *active_text = NULL;
if (gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) != -1)
return TRUE;
active_text = gtk_combo_box_text_get_active_text (combo);
return ce_page_address_is_valid (active_text);
}
const gchar * const gchar *
ce_page_get_security_setting (CEPage *page) ce_page_get_security_setting (CEPage *page)
{ {

View file

@ -90,12 +90,16 @@ gchar **ce_page_get_mac_list (NMClient *client,
void ce_page_setup_mac_combo (GtkComboBoxText *combo, void ce_page_setup_mac_combo (GtkComboBoxText *combo,
const gchar *current_mac, const gchar *current_mac,
gchar **mac_list); gchar **mac_list);
void ce_page_setup_cloned_mac_combo (GtkComboBoxText *combo,
const char *current);
gint ce_get_property_default (NMSetting *setting, gint ce_get_property_default (NMSetting *setting,
const gchar *property_name); const gchar *property_name);
gint ce_spin_output_with_default (GtkSpinButton *spin, gint ce_spin_output_with_default (GtkSpinButton *spin,
gpointer user_data); gpointer user_data);
gboolean ce_page_address_is_valid (const gchar *addr); gboolean ce_page_address_is_valid (const gchar *addr);
gchar *ce_page_trim_address (const gchar *addr); gchar *ce_page_trim_address (const gchar *addr);
char *ce_page_cloned_mac_get (GtkComboBoxText *combo);
gboolean ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo);
typedef enum { typedef enum {
NAME_FORMAT_TYPE, NAME_FORMAT_TYPE,

View file

@ -124,12 +124,17 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="entry_cloned_mac"> <object class="GtkComboBoxText" id="combo_cloned_mac">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="invisible_char">●</property> <property name="active_id">0</property>
<property name="invisible_char_set">True</property> <child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -162,7 +167,7 @@
<property name="xalign">1</property> <property name="xalign">1</property>
<property name="label" translatable="yes">_Cloned Address</property> <property name="label" translatable="yes">_Cloned Address</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="mnemonic_widget">entry_cloned_mac</property> <property name="mnemonic_widget">combo_cloned_mac</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>

View file

@ -76,12 +76,17 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="entry_cloned_mac"> <object class="GtkComboBoxText" id="combo_cloned_mac">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="invisible_char">●</property> <property name="active_id">0</property>
<property name="invisible_char_set">True</property> <child internal-child="entry">
<object class="GtkEntry">
<property name="can_focus">True</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -96,7 +101,7 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">_Cloned Address</property> <property name="label" translatable="yes">_Cloned Address</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="mnemonic_widget">entry_cloned_mac</property> <property name="mnemonic_widget">combo_cloned_mac</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>

View file

@ -1417,8 +1417,8 @@ here</property>
</object> </object>
</child> </child>
<action-widgets> <action-widgets>
<action-widget response="0">details_cancel_button</action-widget> <action-widget response="cancel">details_cancel_button</action-widget>
<action-widget response="0">details_apply_button</action-widget> <action-widget response="apply">details_apply_button</action-widget>
</action-widgets> </action-widgets>
</object> </object>
<object class="GtkListStore" id="details_store"> <object class="GtkListStore" id="details_store">