static gboolean
validate (WirelessSecurity *parent, GError **error)
{
	GtkWidget *entry;
	const char *text;
	gboolean ret = TRUE;

	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry"));
	g_assert (entry);
	text = gtk_entry_get_text (GTK_ENTRY (entry));
	if (!text || !strlen (text)) {
		widget_set_error (entry);
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-username"));
		ret = FALSE;
	} else
		widget_unset_error (entry);

	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry"));
	g_assert (entry);
	text = gtk_entry_get_text (GTK_ENTRY (entry));
	if (!text || !strlen (text)) {
		widget_set_error (entry);
		if (ret) {
			g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-password"));
			ret = FALSE;
		}
	} else
		widget_unset_error (entry);

	return ret;
}
static gboolean
validate (CEPage        *page,
          NMConnection  *connection,
          GError       **error)
{
        GtkWidget *entry;
        GByteArray *ignore;
        gboolean invalid;
        gchar *security;
        NMSettingWireless *setting;
        gboolean ret = TRUE;

        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid")));
        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
        if (invalid) {
                widget_set_error (entry);
                ret = FALSE;
        } else {
                if (ignore)
                        g_byte_array_free (ignore, TRUE);
                widget_unset_error (entry);
        }

        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_mac")));
        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
        if (invalid) {
                widget_set_error (entry);
                ret = FALSE;
        } else {
                if (ignore)
                        g_byte_array_free (ignore, TRUE);
                widget_unset_error (entry);
        }

        entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac"));
        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
        if (invalid) {
                widget_set_error (entry);
                ret = FALSE;
        } else {
                if (ignore)
                        g_byte_array_free (ignore, TRUE);
                widget_unset_error (entry);
        }

        if (!ret)
                return ret;

        ui_to_setting (CE_PAGE_WIFI (page));

        /* A hack to not check the wifi security here */
        setting = CE_PAGE_WIFI (page)->setting;
        security = g_strdup (nm_setting_wireless_get_security (setting));
        g_object_set (setting, NM_SETTING_WIRELESS_SEC, NULL, NULL);
        ret = nm_setting_verify (NM_SETTING (setting), NULL, error);
        g_object_set (setting, NM_SETTING_WIRELESS_SEC, security, NULL);
        g_free (security);

        return ret;
}
static gboolean
validate (EAPMethod *parent)
{
	GtkWidget *widget;
	const char *text;
	gboolean ret = TRUE;

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
	g_assert (widget);
	text = gtk_entry_get_text (GTK_ENTRY (widget));
	if (!text || !strlen (text)) {
		widget_set_error (widget);
		ret = FALSE;
	} else {
		widget_unset_error (widget);
	}

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
	g_assert (widget);
	text = gtk_entry_get_text (GTK_ENTRY (widget));
	if (!text || *text == '\0') {
		widget_set_error (widget);
		ret = FALSE;
	} else {
		widget_unset_error (widget);
	}

	return ret;
}
Пример #4
0
static gboolean
validate (WirelessSecurity *parent, GError **error)
{
	GtkWidget *entry;
	const char *key;
	gsize len;
	int i;

	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry"));
	g_assert (entry);

	key = gtk_entry_get_text (GTK_ENTRY (entry));
	len = key ? strlen (key) : 0;
	if ((len < 8) || (len > 64)) {
		widget_set_error (entry);
		g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: invalid key-length %zu. Must be [8,63] bytes or 64 hex digits"), len);
		return FALSE;
	}

	if (len == 64) {
		/* Hex PSK */
		for (i = 0; i < len; i++) {
			if (!isxdigit (key[i])) {
				widget_set_error (entry);
				g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: cannot interpret key with 64 bytes as hex"));
				return FALSE;
			}
		}
	}
	widget_unset_error (entry);

	/* passphrase can be between 8 and 63 characters inclusive */

	return TRUE;
}
static gboolean
validate (CEPage        *page,
          NMConnection  *connection,
          GError       **error)
{
        CEPageEthernet *self = CE_PAGE_ETHERNET (page);
        gboolean invalid = FALSE;
        GByteArray *ignore;
        GtkWidget *entry;
        gboolean ret = TRUE;

        entry = gtk_bin_get_child (GTK_BIN (self->device_mac));
        if (entry) {
                ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
                if (invalid) {
                        widget_set_error (entry);
                        ret = FALSE;
                } else {
                        if (ignore)
                                g_byte_array_free (ignore, TRUE);
                        widget_unset_error (entry);
                }
        }

        ignore = ce_page_entry_to_mac (self->cloned_mac, ARPHRD_ETHER, &invalid);
        if (invalid) {
                widget_set_error (GTK_WIDGET (self->cloned_mac));
                ret = FALSE;
        } else {
                if (ignore)
                        g_byte_array_free (ignore, TRUE);
                widget_unset_error (GTK_WIDGET (self->cloned_mac));
        }

        if (!ret)
                return ret;

        ui_to_setting (self);

        return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) &&
               nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error);
}
static gboolean
validate (EAPMethod *parent)
{
	GtkWidget *widget;
	const char *text;
	gboolean ret = TRUE;

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
	g_assert (widget);
	text = gtk_entry_get_text (GTK_ENTRY (widget));
	if (!text || !strlen (text)) {
		widget_set_error (widget);
		ret = FALSE;
	} else {
		widget_unset_error (widget);
	}

	/* Check if the password should always be requested */
	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
	g_assert (widget);
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
		widget_unset_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")));
		return ret;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
	g_assert (widget);
	text = gtk_entry_get_text (GTK_ENTRY (widget));
	if (!text || !strlen (text)) {
		widget_set_error (widget);
		ret = FALSE;
	} else {
		widget_unset_error (widget);
	}

	return ret;
}
Пример #7
0
static gboolean
validate (WirelessSecurity *parent, const GByteArray *ssid)
{
	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
	GtkWidget *entry;
	const char *key;
	int i;

	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
	g_assert (entry);

	key = gtk_entry_get_text (GTK_ENTRY (entry));
	if (!key) {
		widget_set_error (entry);
		return FALSE;
	}

	if (sec->type == NM_WEP_KEY_TYPE_KEY) {
		if ((strlen (key) == 10) || (strlen (key) == 26)) {
			for (i = 0; i < strlen (key); i++) {
				if (!isxdigit (key[i])) {
					widget_set_error (entry);
					return FALSE;
				}
			}
		} else if ((strlen (key) == 5) || (strlen (key) == 13)) {
			for (i = 0; i < strlen (key); i++) {
				if (!isascii (key[i])) {
					widget_set_error (entry);
					return FALSE;
				}
			}
		} else {
			widget_set_error (entry);
			return FALSE;
		}
	} else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) {
		if (!strlen (key) || (strlen (key) > 64)) {
			widget_set_error (entry);
			return FALSE;
		}
	}
	widget_unset_error (entry);

	return TRUE;
}
Пример #8
0
gboolean
eap_method_validate_filepicker (GtkBuilder *builder,
                                const char *name,
                                guint32 item_type,
                                const char *password,
                                NMSetting8021xCKFormat *out_format,
                                GError **error)
{
	GtkWidget *widget;
	char *filename;
	NMSetting8021x *setting;
	gboolean success = TRUE;

	if (item_type == TYPE_PRIVATE_KEY) {
		if (!password || *password == '\0')
			success = FALSE;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
	g_assert (widget);
	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
	if (!filename) {
		if (item_type != TYPE_CA_CERT) {
			success = FALSE;
			g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("no file selected"));
		}
		goto out;
	}

	if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
		success = FALSE;
		goto out;
	}

	setting = (NMSetting8021x *) nm_setting_802_1x_new ();

	success = FALSE;
	if (item_type == TYPE_PRIVATE_KEY) {
		if (nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error))
			success = TRUE;
	} else if (item_type == TYPE_CLIENT_CERT) {
		if (nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error))
			success = TRUE;
	} else if (item_type == TYPE_CA_CERT) {
		if (nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error))
			success = TRUE;
	} else
		g_warning ("%s: invalid item type %d.", __func__, item_type);

	g_object_unref (setting);

out:
	g_free (filename);

	if (!success && error && !*error)
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("unspecified error validating eap-method file"));

	if (success)
		widget_unset_error (widget);
	else
		widget_set_error (widget);
	return success;
}
static gboolean
validate (EAPMethod *parent, GError **error)
{
	NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
	GtkWidget *widget;
	const char *password, *identity;
	GError *local = NULL;
	gboolean ret = TRUE;

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
	g_assert (widget);
	identity = gtk_entry_get_text (GTK_ENTRY (widget));
	if (!identity || !strlen (identity)) {
		widget_set_error (widget);
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-TLS identity"));
		ret = FALSE;
	} else {
		widget_unset_error (widget);
	}

	if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) {
		widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")));
		if (ret) {
			g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: %s"), local->message);
			ret = FALSE;
		}
		g_clear_error (&local);
	} else if (eap_method_ca_cert_required (parent->builder, "eap_tls_ca_cert_not_required_checkbox", "eap_tls_ca_cert_button")) {
		widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")));
		if (ret) {
			g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: no certificate specified"));
			ret = FALSE;
		}
	}

	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
	g_assert (widget);
	password = gtk_entry_get_text (GTK_ENTRY (widget));

	if (!eap_method_validate_filepicker (parent->builder,
	                                     "eap_tls_private_key_button",
	                                     TYPE_PRIVATE_KEY,
	                                     password,
	                                     &format,
	                                     &local)) {
		if (ret) {
			g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS private-key: %s"), local->message);
			ret = FALSE;
		}
		g_clear_error (&local);
		widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")));
	}

	if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
		if (!eap_method_validate_filepicker (parent->builder, "eap_tls_user_cert_button", TYPE_CLIENT_CERT, NULL, NULL, &local)) {
			if (ret) {
				g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS user-certificate: %s"), local->message);
				ret = FALSE;
			}
			g_clear_error (&local);
			widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")));
		}
	}

	return ret;
}
static gboolean
ui_to_setting (CEPageIP4 *page)
{
        const gchar *method;
        gboolean ignore_auto_dns;
        gboolean ignore_auto_routes;
        gboolean never_default;
        GPtrArray *addresses = NULL;
        GArray *dns_servers = NULL;
        GPtrArray *routes = NULL;
        GList *children, *l;
        gboolean ret = TRUE;

        if (!gtk_switch_get_active (page->enabled)) {
                method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
        } else {
                switch (gtk_combo_box_get_active (page->method)) {
                case IP4_METHOD_MANUAL:
                        method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
                        break;
                case IP4_METHOD_LINK_LOCAL:
                        method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL;
                        break;
                default:
                case IP4_METHOD_AUTO:
                        method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
                        break;
                }
        }

        addresses = g_ptr_array_new_with_free_func (free_addr);
        children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text_address;
                const gchar *text_netmask;
                const gchar *text_gateway;
                struct in_addr tmp_addr;
                struct in_addr tmp_gateway = { 0 };
                guint32 prefix;
                guint32 empty_val = 0;
                GArray *addr;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text_address = gtk_entry_get_text (entry);
                text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "network")));
                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));

                if (!*text_address && !*text_netmask && !*text_gateway) {
                        /* ignore empty rows */
                        widget_unset_error (GTK_WIDGET (entry));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "network"));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        continue;
                }

                if (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                }

                if (!parse_netmask (text_netmask, &prefix)) {
                        widget_set_error (g_object_get_data (G_OBJECT (row), "network"));
                        ret = FALSE;
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "network"));
                }

                if (text_gateway && *text_gateway && inet_pton (AF_INET, text_gateway, &tmp_gateway) <= 0) {
                        widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        ret = FALSE;
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                }

                if (!ret)
                        continue;

                addr = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
                g_array_append_val (addr, tmp_addr.s_addr);
                g_array_append_val (addr, prefix);
                if (tmp_gateway.s_addr)
                        g_array_append_val (addr, tmp_gateway.s_addr);
                else
                        g_array_append_val (addr, empty_val);
                g_ptr_array_add (addresses, addr);
        }
        g_list_free (children);

        if (addresses->len == 0) {
                g_ptr_array_free (addresses, TRUE);
                addresses = NULL;
        }

        dns_servers = g_array_new (FALSE, FALSE, sizeof (guint));
        children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text;
                struct in_addr tmp_addr;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text = gtk_entry_get_text (entry);
                if (!*text) {
                        /* ignore empty rows */
                        widget_unset_error (GTK_WIDGET (entry));
                        continue;
                }

                if (inet_pton (AF_INET, text, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                        g_array_append_val (dns_servers, tmp_addr.s_addr);
                }
        }
        g_list_free (children);


        routes = g_ptr_array_new_with_free_func (free_addr);
        children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text_address;
                const gchar *text_netmask;
                const gchar *text_gateway;
                const gchar *text_metric;
                struct in_addr tmp_addr = { 0 };
                guint32 address, netmask, gateway, metric;
                GArray *route;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text_address = gtk_entry_get_text (entry);
                text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "netmask")));
                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
                text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));

                if (!*text_address && !*text_netmask && !*text_gateway && !*text_metric) {
                        /* ignore empty rows */
                        continue;
                }

                if (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                        address = tmp_addr.s_addr;
                }

                if (!parse_netmask (text_netmask, &netmask)) {
                        widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask")));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask")));
                }

                if (inet_pton (AF_INET, text_gateway, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")));
                        gateway = tmp_addr.s_addr;
                }

                metric = 0;
                if (*text_metric) {
                        errno = 0;
                        metric = strtoul (text_metric, NULL, 10);
                        if (errno) {
                                widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
                                ret = FALSE;
                        } else {
                                widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
                        }
                } else {
                        widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
                }

                if (!ret)
                        continue;

                route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
                g_array_append_val (route, address);
                g_array_append_val (route, netmask);
                g_array_append_val (route, gateway);
                g_array_append_val (route, metric);
                g_ptr_array_add (routes, route);
        }
        g_list_free (children);

        if (routes->len == 0) {
                g_ptr_array_free (routes, TRUE);
                routes = NULL;
        }

        if (!ret)
                goto out;

        ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
        ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
        never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));

        g_object_set (page->setting,
                      NM_SETTING_IP4_CONFIG_METHOD, method,
                      NM_SETTING_IP4_CONFIG_ADDRESSES, addresses,
                      NM_SETTING_IP4_CONFIG_DNS, dns_servers,
                      NM_SETTING_IP4_CONFIG_ROUTES, routes,
                      NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
                      NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
                      NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
                      NULL);

out:
        if (addresses)
                g_ptr_array_free (addresses, TRUE);

        if (dns_servers)
                g_array_free (dns_servers, TRUE);

        if (routes)
                g_ptr_array_free (routes, TRUE);

        return ret;
}
static gboolean
ui_to_setting (CEPageIP6 *page)
{
        const gchar *method;
        gboolean ignore_auto_dns;
        gboolean ignore_auto_routes;
        gboolean never_default;
        GList *children, *l;
        gboolean ret = TRUE;

        if (!gtk_switch_get_active (page->enabled)) {
                method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
        } else {
                switch (gtk_combo_box_get_active (page->method)) {
                case IP6_METHOD_MANUAL:
                        method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
                        break;
                case IP6_METHOD_LINK_LOCAL:
                        method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
                        break;
                case IP6_METHOD_DHCP:
                        method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
                        break;
                default:
                case IP6_METHOD_AUTO:
                        method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
                        break;
                }
        }

        nm_setting_ip6_config_clear_addresses (page->setting);
        if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
                children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
        else
                children = NULL;

        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text_address;
                const gchar *text_prefix;
                const gchar *text_gateway;
                struct in6_addr tmp_addr;
                struct in6_addr tmp_gateway;
                guint32 prefix;
                gchar *end;
                NMIP6Address *addr;
                gboolean have_gateway = FALSE;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text_address = gtk_entry_get_text (entry);
                text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));

                if (!*text_address && !*text_prefix && !*text_gateway) {
                        /* ignore empty rows */
                        widget_unset_error (GTK_WIDGET (entry));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        continue;
                }

                if (inet_pton (AF_INET6, text_address, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                }

                prefix = strtoul (text_prefix, &end, 10);
                if (!end || *end || prefix == 0 || prefix > 128) {
                        widget_set_error (g_object_get_data (G_OBJECT (row), "prefix"));
                        ret = FALSE;
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
                }

                if (text_gateway && *text_gateway) {
                        if (inet_pton (AF_INET6, text_gateway, &tmp_gateway) <= 0) {
                                widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
                                ret = FALSE;
                        } else {
                                if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_gateway))
                                        have_gateway = TRUE;
                                widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        }
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                }

                if (!ret)
                        continue;

                addr = nm_ip6_address_new ();
                nm_ip6_address_set_address (addr, &tmp_addr);
                nm_ip6_address_set_prefix (addr, prefix);
                if (have_gateway)
                        nm_ip6_address_set_gateway (addr, &tmp_gateway);
                nm_setting_ip6_config_add_address (page->setting, addr);
        }
        g_list_free (children);

        nm_setting_ip6_config_clear_dns (page->setting);
        if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) ||
            g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) ||
            g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
                children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
        else
                children = NULL;

        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text;
                struct in6_addr tmp_addr;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text = gtk_entry_get_text (entry);
                if (!*text) {
                        /* ignore empty rows */
                        widget_unset_error (GTK_WIDGET (entry));
                        continue;
                }

                if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                        nm_setting_ip6_config_add_dns (page->setting, &tmp_addr);
                }
        }
        g_list_free (children);

        nm_setting_ip6_config_clear_routes (page->setting);
        if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) ||
            g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) ||
            g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
                children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
        else
                children = NULL;

        for (l = children; l; l = l->next) {
                GtkWidget *row = l->data;
                GtkEntry *entry;
                const gchar *text_address;
                const gchar *text_prefix;
                const gchar *text_gateway;
                const gchar *text_metric;
                struct in6_addr dest, gateway;
                guint32 prefix, metric;
                gchar *end;
                NMIP6Route *route;

                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
                if (!entry)
                        continue;

                text_address = gtk_entry_get_text (entry);
                text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
                text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));

                if (!*text_address && !*text_prefix && !*text_gateway && !*text_metric) {
                        /* ignore empty rows */
                        widget_unset_error (GTK_WIDGET (entry));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
                        continue;
                }

                if (inet_pton (AF_INET6, text_address, &dest) <= 0) {
                        widget_set_error (GTK_WIDGET (entry));
                        ret = FALSE;
                } else {
                        widget_unset_error (GTK_WIDGET (entry));
                }

                prefix = strtoul (text_prefix, &end, 10);
                if (!end || *end || prefix == 0 || prefix > 128) {
                        widget_set_error (g_object_get_data (G_OBJECT (row), "prefix"));
                        ret = FALSE;
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
                }

                if (inet_pton (AF_INET6, text_gateway, &gateway) <= 0) {
                        widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
                        ret = FALSE;
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
                }

                metric = 0;
                if (*text_metric) {
                        errno = 0;
                        metric = strtoul (text_metric, NULL, 10);
                        if (errno) {
                                widget_set_error (g_object_get_data (G_OBJECT (row), "metric"));
                                ret = FALSE;
                        } else {
                                widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
                        }
                } else {
                        widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
                }

                if (!ret)
                        continue;

                route = nm_ip6_route_new ();
                nm_ip6_route_set_dest (route, &dest);
                nm_ip6_route_set_prefix (route, prefix);
                nm_ip6_route_set_next_hop (route, &gateway);
                nm_ip6_route_set_metric (route, metric);
                nm_setting_ip6_config_add_route (page->setting, route);
                nm_ip6_route_unref (route);
        }
        g_list_free (children);

        if (!ret)
                goto out;

        ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
        ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
        never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));

        g_object_set (page->setting,
                      NM_SETTING_IP6_CONFIG_METHOD, method,
                      NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
                      NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
                      NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
                      NULL);

out:

        return ret;
}