mirror of
				https://github.com/max-moser/network-manager-wireguard.git
				synced 2025-11-04 09:03:49 +03:00 
			
		
		
		
	Implement import/export and connection editor UI
This commit is contained in:
		
							parent
							
								
									3209433372
								
							
						
					
					
						commit
						94046d0b8c
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -65,30 +65,56 @@ typedef struct {
 | 
				
			|||||||
#define COL_AUTH_PAGE 1
 | 
					#define COL_AUTH_PAGE 1
 | 
				
			||||||
#define COL_AUTH_TYPE 2
 | 
					#define COL_AUTH_TYPE 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					is_empty(const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gboolean empty = FALSE;
 | 
				
			||||||
 | 
						gchar *tmp = g_strdup(str);
 | 
				
			||||||
 | 
						tmp = g_strstrip(tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!tmp || !tmp[0]){
 | 
				
			||||||
 | 
							empty = TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g_free(tmp);
 | 
				
			||||||
 | 
						return empty;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_interface_ip4_entry(const char *str)
 | 
					check_interface_ip4_entry(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	gs_free char *str_clone = NULL;
 | 
						return is_ip4((char *)str);
 | 
				
			||||||
	char *str_iter;
 | 
					}
 | 
				
			||||||
	const char *tok;
 | 
					
 | 
				
			||||||
	int count = 0;
 | 
					static gboolean
 | 
				
			||||||
 | 
					check_interface_ip6_entry(const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return is_ip6((char *)str);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					check_interface_dns_entry(const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(is_empty(str)){
 | 
				
			||||||
 | 
							return TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(is_ip4(str)){
 | 
				
			||||||
 | 
							return TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(is_ip6(str)){
 | 
				
			||||||
 | 
							return TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(!str || !str[0]) {
 | 
					 | 
				
			||||||
	return FALSE;
 | 
						return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	str_clone = g_strdup(str);
 | 
					static gboolean
 | 
				
			||||||
	str_iter = str_clone;
 | 
					check_interface_mtu_entry(const char *str)
 | 
				
			||||||
	while((tok = strsep(&str_iter, "."))){
 | 
					{
 | 
				
			||||||
		count ++;
 | 
						if(is_empty(str)){
 | 
				
			||||||
		// each number in an IP4 must be: 0 <= X <= 255
 | 
							return TRUE;
 | 
				
			||||||
		if(!g_ascii_string_to_unsigned(tok, 10, 0, 255, NULL, NULL)){
 | 
					 | 
				
			||||||
			return FALSE;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
						else if(!g_ascii_string_to_unsigned(str, 10, 0, 1500, NULL, NULL)){
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// an IP4 consists of 4 segments
 | 
					 | 
				
			||||||
	if(count != 4){
 | 
					 | 
				
			||||||
		return FALSE;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -98,11 +124,7 @@ check_interface_ip4_entry(const char *str)
 | 
				
			|||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_interface_private_key(const char *str)
 | 
					check_interface_private_key(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	gs_free char *str_clone = NULL;
 | 
						if(is_empty(str)){
 | 
				
			||||||
	str_clone = g_strdup(str);
 | 
					 | 
				
			||||||
	str_clone = g_strstrip(str_clone);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!g_strcmp0("", str_clone)){
 | 
					 | 
				
			||||||
		return FALSE;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -113,10 +135,7 @@ check_interface_private_key(const char *str)
 | 
				
			|||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_interface_listen_port(const char *str)
 | 
					check_interface_listen_port(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	gs_free char *str_clone = NULL;
 | 
						if(!g_ascii_string_to_unsigned(str, 10, 0, 65535, NULL, NULL)){
 | 
				
			||||||
	str_clone = g_strdup(str);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!g_ascii_string_to_unsigned(str_clone, 10, 0, 65535, NULL, NULL)){
 | 
					 | 
				
			||||||
		return FALSE;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -124,58 +143,54 @@ check_interface_listen_port(const char *str)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_peer_public_key(const char *str)
 | 
					check_peer_public_key(const char *str){
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	// TODO
 | 
					 | 
				
			||||||
	return check_interface_private_key(str);
 | 
						return check_interface_private_key(str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_peer_allowed_ips(const char *str)
 | 
					check_peer_allowed_ips(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// TODO
 | 
						gchar **ips;
 | 
				
			||||||
	return check_interface_ip4_entry(str);
 | 
						int idx = 0;
 | 
				
			||||||
 | 
						gboolean success = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ips = g_strsplit_set(str, ", \t", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while(ips && ips[idx]){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(is_empty(ips[idx])){
 | 
				
			||||||
 | 
								idx++;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// there should not be any trailing commas, etc. anymore
 | 
				
			||||||
 | 
							// -> if any of the items is not a valid IPv4 or IPv6 address: error!
 | 
				
			||||||
 | 
							if(!is_ip4(ips[idx]) && !is_ip6(ips[idx])){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							idx++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						g_strfreev(ips);
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_peer_endpoint(const char *str)
 | 
					check_peer_endpoint(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// TODO
 | 
						return is_ip4((char *)str) || is_ip6((char *)str);
 | 
				
			||||||
	return check_interface_ip4_entry(str);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static gboolean
 | 
					 | 
				
			||||||
check_gateway_entry (const char *str)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	gs_free char *str_clone = NULL;
 | 
					 | 
				
			||||||
	char *str_iter;
 | 
					 | 
				
			||||||
	const char *tok;
 | 
					 | 
				
			||||||
	gboolean success = FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!str || !str[0])
 | 
					 | 
				
			||||||
		return FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	str_clone = g_strdup (str);
 | 
					 | 
				
			||||||
	str_iter = str_clone;
 | 
					 | 
				
			||||||
	while ((tok = strsep (&str_iter, " \t,"))) {
 | 
					 | 
				
			||||||
		if (   tok[0]
 | 
					 | 
				
			||||||
		    && (nmovpn_remote_parse (tok,
 | 
					 | 
				
			||||||
		                             NULL,
 | 
					 | 
				
			||||||
		                             NULL,
 | 
					 | 
				
			||||||
		                             NULL,
 | 
					 | 
				
			||||||
		                             NULL,
 | 
					 | 
				
			||||||
		                             NULL) != -1))
 | 
					 | 
				
			||||||
		   return FALSE;
 | 
					 | 
				
			||||||
		success = TRUE;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return success;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef gboolean (*CheckFunc)(const char *str);
 | 
					typedef gboolean (*CheckFunc)(const char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// helper function to reduce boilerplate code in 'check_validity()'
 | 
					// helper function to reduce boilerplate code in 'check_validity()'
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check (OpenvpnEditorPrivate *priv, char *widget_name, CheckFunc chk, GError **error)
 | 
					check (OpenvpnEditorPrivate *priv,
 | 
				
			||||||
 | 
							char *widget_name,
 | 
				
			||||||
 | 
							CheckFunc chk, const char *key,
 | 
				
			||||||
 | 
							gboolean set_error,
 | 
				
			||||||
 | 
							GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	GtkWidget *widget;
 | 
						GtkWidget *widget;
 | 
				
			||||||
@ -186,11 +201,11 @@ check (OpenvpnEditorPrivate *priv, char *widget_name, CheckFunc chk, GError **er
 | 
				
			|||||||
	else {
 | 
						else {
 | 
				
			||||||
		gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error");
 | 
							gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error");
 | 
				
			||||||
		// only set the error if it's NULL
 | 
							// only set the error if it's NULL
 | 
				
			||||||
		if(error == NULL){
 | 
							if(error == NULL && set_error){
 | 
				
			||||||
			g_set_error (error,
 | 
								g_set_error (error,
 | 
				
			||||||
						NMV_EDITOR_PLUGIN_ERROR,
 | 
											NMV_EDITOR_PLUGIN_ERROR,
 | 
				
			||||||
						NMV_EDITOR_PLUGIN_ERROR_INVALID_PROPERTY,
 | 
											NMV_EDITOR_PLUGIN_ERROR_INVALID_PROPERTY,
 | 
				
			||||||
						NM_WG_KEY_ADDR_IP4);
 | 
											key);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return FALSE;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -198,6 +213,28 @@ check (OpenvpnEditorPrivate *priv, char *widget_name, CheckFunc chk, GError **er
 | 
				
			|||||||
	return TRUE;
 | 
						return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					set_error_class(OpenvpnEditorPrivate *priv, char *widget_name, gboolean error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, widget_name));
 | 
				
			||||||
 | 
						if(error){
 | 
				
			||||||
 | 
							gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else{
 | 
				
			||||||
 | 
							gtk_style_context_remove_class (gtk_widget_get_style_context (widget), "error");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					is_filled_out(OpenvpnEditorPrivate *priv, char *widget_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *str;
 | 
				
			||||||
 | 
						GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, widget_name));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text(GTK_ENTRY (widget));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return !is_empty(str);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_validity (OpenvpnEditor *self, GError **error)
 | 
					check_validity (OpenvpnEditor *self, GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -206,27 +243,73 @@ check_validity (OpenvpnEditor *self, GError **error)
 | 
				
			|||||||
	GtkTreeModel *model;
 | 
						GtkTreeModel *model;
 | 
				
			||||||
	GtkTreeIter iter;
 | 
						GtkTreeIter iter;
 | 
				
			||||||
	const char *contype = NULL;
 | 
						const char *contype = NULL;
 | 
				
			||||||
	gboolean success;
 | 
						gboolean success = TRUE;
 | 
				
			||||||
 | 
						gboolean ip4_ok = TRUE;
 | 
				
			||||||
 | 
						gboolean ip6_ok = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// check the various input fields for errors
 | 
						// check the various input fields for errors
 | 
				
			||||||
	if(!check(priv, "interface_ip4_entry", check_interface_ip4_entry, error)){
 | 
						if(!check(priv, "interface_ip4_entry", check_interface_ip4_entry, NM_WG_KEY_ADDR_IP4, FALSE, error)){
 | 
				
			||||||
 | 
							ip4_ok = FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(!check(priv, "interface_ip6_entry", check_interface_ip6_entry, NM_WG_KEY_ADDR_IP6, FALSE, error)){
 | 
				
			||||||
 | 
							ip6_ok = FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(!check(priv, "interface_private_key_entry", check_interface_private_key, NM_WG_KEY_PRIVATE_KEY, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(!check(priv, "interface_private_key_entry", check_interface_private_key, error)){
 | 
						if(!check(priv, "interface_port_entry", check_interface_listen_port, NM_WG_KEY_LISTEN_PORT, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(!check(priv, "interface_port_entry", check_interface_listen_port, error)){
 | 
						if(!check(priv, "interface_dns_entry", check_interface_dns_entry, NM_WG_KEY_DNS, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(!check(priv, "peer_public_key_entry", check_peer_public_key, error)){
 | 
						if(!check(priv, "interface_mtu_entry", check_interface_mtu_entry, NM_WG_KEY_MTU, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(!check(priv, "peer_allowed_ips_entry", check_peer_allowed_ips, error)){
 | 
						if(!check(priv, "peer_public_key_entry", check_peer_public_key, NM_WG_KEY_PUBLIC_KEY, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(!check(priv, "peer_endpoint_entry", check_peer_endpoint, error)){
 | 
						if(!check(priv, "peer_allowed_ips_entry", check_peer_allowed_ips, NM_WG_KEY_ALLOWED_IPS, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if(!check(priv, "peer_endpoint_entry", check_peer_endpoint, NM_WG_KEY_ENDPOINT, TRUE, error)){
 | 
				
			||||||
 | 
							success = FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// pre-up, post-up, pre-down, post-down are scripts and don't get validated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(ip4_ok && ip6_ok){
 | 
				
			||||||
 | 
							set_error_class(priv, "interface_ip4_entry", FALSE);
 | 
				
			||||||
 | 
							set_error_class(priv, "interface_ip6_entry", FALSE);
 | 
				
			||||||
 | 
							// this should be fine, actually
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(ip4_ok){
 | 
				
			||||||
 | 
							// IP6 is filled out but not ok
 | 
				
			||||||
 | 
							if(is_filled_out(priv, "interface_ip6_entry")){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
								g_set_error (error,
 | 
				
			||||||
 | 
											NMV_EDITOR_PLUGIN_ERROR,
 | 
				
			||||||
 | 
											NMV_EDITOR_PLUGIN_ERROR_INVALID_PROPERTY,
 | 
				
			||||||
 | 
											NM_WG_KEY_ADDR_IP6);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else{
 | 
				
			||||||
 | 
								set_error_class(priv, "interface_ip4_entry", FALSE);
 | 
				
			||||||
 | 
								set_error_class(priv, "interface_ip6_entry", FALSE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(ip6_ok){
 | 
				
			||||||
 | 
							// IP4 is filled out but not ok
 | 
				
			||||||
 | 
							if(is_filled_out(priv, "interface_ip4_entry")){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
								g_set_error (error,
 | 
				
			||||||
 | 
											NMV_EDITOR_PLUGIN_ERROR,
 | 
				
			||||||
 | 
											NMV_EDITOR_PLUGIN_ERROR_INVALID_PROPERTY,
 | 
				
			||||||
 | 
											NM_WG_KEY_ADDR_IP4);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else{
 | 
				
			||||||
 | 
								set_error_class(priv, "interface_ip4_entry", FALSE);
 | 
				
			||||||
 | 
								set_error_class(priv, "interface_ip6_entry", FALSE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "auth_combo"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "auth_combo"));
 | 
				
			||||||
@ -367,11 +450,41 @@ init_editor_plugin (OpenvpnEditor *self, NMConnection *connection, GError **erro
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Local IPv6 address
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_ip6_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP6);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// DNS
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_dns_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_DNS);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Private Key
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_mtu_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_MTU);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Interface Private Key
 | 
						// Interface Private Key
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_entry"));
 | 
				
			||||||
	g_return_val_if_fail (widget != NULL, FALSE);
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
	if (s_vpn) {
 | 
						if (s_vpn) {
 | 
				
			||||||
		value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP4);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRIVATE_KEY);
 | 
				
			||||||
		if (value)
 | 
							if (value)
 | 
				
			||||||
			gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -381,7 +494,57 @@ init_editor_plugin (OpenvpnEditor *self, NMConnection *connection, GError **erro
 | 
				
			|||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_port_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_port_entry"));
 | 
				
			||||||
	g_return_val_if_fail (widget != NULL, FALSE);
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
	if (s_vpn) {
 | 
						if (s_vpn) {
 | 
				
			||||||
		value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP4);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_LISTEN_PORT);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Pre Up
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_pre_up_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRE_UP);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Post Up
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_post_up_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_POST_UP);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Pre Down
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_pre_down_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRE_DOWN);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Post Down
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_post_down_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_POST_DOWN);
 | 
				
			||||||
 | 
							if (value)
 | 
				
			||||||
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Interface Preshared Key
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_psk_entry"));
 | 
				
			||||||
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
 | 
						if (s_vpn) {
 | 
				
			||||||
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRESHARED_KEY);
 | 
				
			||||||
		if (value)
 | 
							if (value)
 | 
				
			||||||
			gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -392,7 +555,7 @@ init_editor_plugin (OpenvpnEditor *self, NMConnection *connection, GError **erro
 | 
				
			|||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry"));
 | 
				
			||||||
	g_return_val_if_fail (widget != NULL, FALSE);
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
	if (s_vpn) {
 | 
						if (s_vpn) {
 | 
				
			||||||
		value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP4);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PUBLIC_KEY);
 | 
				
			||||||
		if (value)
 | 
							if (value)
 | 
				
			||||||
			gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -402,7 +565,7 @@ init_editor_plugin (OpenvpnEditor *self, NMConnection *connection, GError **erro
 | 
				
			|||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_allowed_ips_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_allowed_ips_entry"));
 | 
				
			||||||
	g_return_val_if_fail (widget != NULL, FALSE);
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
	if (s_vpn) {
 | 
						if (s_vpn) {
 | 
				
			||||||
		value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP4);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ALLOWED_IPS);
 | 
				
			||||||
		if (value)
 | 
							if (value)
 | 
				
			||||||
			gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -412,7 +575,7 @@ init_editor_plugin (OpenvpnEditor *self, NMConnection *connection, GError **erro
 | 
				
			|||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_endpoint_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_endpoint_entry"));
 | 
				
			||||||
	g_return_val_if_fail (widget != NULL, FALSE);
 | 
						g_return_val_if_fail (widget != NULL, FALSE);
 | 
				
			||||||
	if (s_vpn) {
 | 
						if (s_vpn) {
 | 
				
			||||||
		value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ADDR_IP4);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_ENDPOINT);
 | 
				
			||||||
		if (value)
 | 
							if (value)
 | 
				
			||||||
			gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
								gtk_entry_set_text (GTK_ENTRY (widget), value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -576,18 +739,66 @@ update_connection (NMVpnEditor *iface,
 | 
				
			|||||||
	if (str && str[0])
 | 
						if (str && str[0])
 | 
				
			||||||
		nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_ADDR_IP4, str);
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_ADDR_IP4, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// local ip6
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_ip6_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_ADDR_IP6, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// private key
 | 
						// private key
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_entry"));
 | 
				
			||||||
	str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
	if (str && str[0])
 | 
						if (str && str[0])
 | 
				
			||||||
		nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRIVATE_KEY, str);
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRIVATE_KEY, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// dns
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_dns_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_DNS, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// mtu
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_mtu_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_MTU, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// listen port
 | 
						// listen port
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_port_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_port_entry"));
 | 
				
			||||||
	str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
	if (str && str[0])
 | 
						if (str && str[0])
 | 
				
			||||||
		nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_LISTEN_PORT, str);
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_LISTEN_PORT, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pre up script
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_pre_up_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRE_UP, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// post up script
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_post_up_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_POST_UP, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pre up script
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_pre_down_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRE_DOWN, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// post down script
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_post_down_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_POST_DOWN, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// preshared key
 | 
				
			||||||
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_psk_entry"));
 | 
				
			||||||
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
						if (str && str[0])
 | 
				
			||||||
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRESHARED_KEY, str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// peer public key
 | 
						// peer public key
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry"));
 | 
				
			||||||
	str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
						str = gtk_entry_get_text (GTK_ENTRY (widget));
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										196
									
								
								shared/utils.c
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								shared/utils.c
									
									
									
									
									
								
							@ -248,3 +248,199 @@ out_fail:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// check if the given string looks like an IPv4 address
 | 
				
			||||||
 | 
					// that is, four segments of numbers (0-255), separated by dots
 | 
				
			||||||
 | 
					// additionally, there may be a port suffix (separated from the address by a colon; 0 - 65535)
 | 
				
			||||||
 | 
					// and/or a subnet (separated by the rest by a slash; 0 - 32)
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					is_ip4(char *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int idx = 0;
 | 
				
			||||||
 | 
						int dots = 0;
 | 
				
			||||||
 | 
						gchar **parts;
 | 
				
			||||||
 | 
						gchar **tmp;
 | 
				
			||||||
 | 
						gchar **tmp2;
 | 
				
			||||||
 | 
						gchar *lastpart;
 | 
				
			||||||
 | 
						gboolean success = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!addr){
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while(addr && addr[idx]){
 | 
				
			||||||
 | 
							if(addr[idx] == '.'){
 | 
				
			||||||
 | 
								dots++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							idx++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(dots != 3){
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts = g_strsplit(addr, ".", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// iterate over the first three parts, which cannot be anything else than numbers
 | 
				
			||||||
 | 
						for(idx = 0; idx < 3; idx++){
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(parts[idx], 10, 0, 255, NULL, NULL)){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
								goto ip4end;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if the last part is a number, we're fine
 | 
				
			||||||
 | 
						lastpart = parts[3];
 | 
				
			||||||
 | 
						if(g_ascii_string_to_unsigned(lastpart, 10, 0, 255, NULL, NULL)){
 | 
				
			||||||
 | 
							success = TRUE;
 | 
				
			||||||
 | 
							goto ip4end;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// might have a subnet suffix after a slash (e.g. 192.168.1.254/24)
 | 
				
			||||||
 | 
						// might have a port suffix after a colon (e.g. 192.168.1.254:8080)
 | 
				
			||||||
 | 
						if(g_strrstr(lastpart, ":") && g_strrstr(lastpart, "/")){
 | 
				
			||||||
 | 
							tmp = g_strsplit(lastpart, ":", 2);
 | 
				
			||||||
 | 
							tmp2 = g_strsplit(tmp[1], "/", 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp[0], 10, 0, 255, NULL, NULL)){
 | 
				
			||||||
 | 
								// the last part of the IP
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp2[0], 10, 0, 65535, NULL, NULL)){
 | 
				
			||||||
 | 
								// the port
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp2[1], 10, 0, 32, NULL, NULL)){
 | 
				
			||||||
 | 
								// the subnet portion
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_strfreev(tmp);
 | 
				
			||||||
 | 
							g_strfreev(tmp2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(g_strrstr(lastpart, "/")){
 | 
				
			||||||
 | 
							tmp = g_strsplit(lastpart, "/", 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp[0], 10, 0, 255, NULL, NULL)){
 | 
				
			||||||
 | 
								// the last part of the IP
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp[1], 10, 0, 32, NULL, NULL)){
 | 
				
			||||||
 | 
								// the subnet portion
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_strfreev(tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(g_strrstr(lastpart, ":")){
 | 
				
			||||||
 | 
							tmp = g_strsplit(lastpart, ":", 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp[0], 10, 0, 255, NULL, NULL)){
 | 
				
			||||||
 | 
								// the last part of the IP
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_ascii_string_to_unsigned(tmp[1], 10, 0, 65535, NULL, NULL)){
 | 
				
			||||||
 | 
								// the port
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_strfreev(tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else{
 | 
				
			||||||
 | 
							// we have neither a port nor a subnet suffix, but it's not a number either
 | 
				
			||||||
 | 
							success = FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ip4end:
 | 
				
			||||||
 | 
						g_strfreev(parts);
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// check if the given string looks like an IPv6 address
 | 
				
			||||||
 | 
					// that is, several segments of up to 4 hexadecimal digits
 | 
				
			||||||
 | 
					// separated by colons, possibly followed by a slash and a subnet (0 - 128)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// if there are several zeroes in adjacent segments,
 | 
				
			||||||
 | 
					// those segments may be omitted
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					is_ip6(char *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gchar **parts;
 | 
				
			||||||
 | 
						gchar **tmp;
 | 
				
			||||||
 | 
						gchar *lastpart;
 | 
				
			||||||
 | 
						int len = 0;
 | 
				
			||||||
 | 
						int i = 0;
 | 
				
			||||||
 | 
						int num_empty = 0;
 | 
				
			||||||
 | 
						int num_colons = 0;
 | 
				
			||||||
 | 
						gboolean success = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!addr){
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if(!g_strrstr(addr, ":")){
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while(addr && addr[i]){
 | 
				
			||||||
 | 
							if(addr[i] == ':'){
 | 
				
			||||||
 | 
								num_colons++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if(num_colons < 2){
 | 
				
			||||||
 | 
							// an IPv6 has to contain at least two colons
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts = g_strsplit(addr, ":", 0);
 | 
				
			||||||
 | 
						while(parts && parts[len]){
 | 
				
			||||||
 | 
							len++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						num_empty = 0;
 | 
				
			||||||
 | 
						for(i = 0; i < (len-1); i++){
 | 
				
			||||||
 | 
							if((i == 0) && (!g_strcmp0("", parts[i]))){
 | 
				
			||||||
 | 
								// the beginning may be empty (e.g. in "::1")
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!g_strcmp0("", parts[i]) && (num_empty < 1)){
 | 
				
			||||||
 | 
								// there may be one "skipped" part in the IP6
 | 
				
			||||||
 | 
								num_empty++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if(!g_ascii_string_to_unsigned(parts[i], 16, 0, 65536, NULL, NULL)){
 | 
				
			||||||
 | 
								// the rest of the parts have to be numerals between 0 and 16^4 in hex
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
								goto ip6end;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastpart = parts[len-1];
 | 
				
			||||||
 | 
						if(g_strrstr(lastpart, "/")){
 | 
				
			||||||
 | 
							// we have a subnet portion
 | 
				
			||||||
 | 
							tmp = g_strsplit(lastpart, "/", 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(g_strcmp0("", tmp[0]) && !g_ascii_string_to_unsigned(tmp[0], 16, 0, 65536, NULL, NULL)){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if(!g_ascii_string_to_unsigned(tmp[1], 10, 0, 128, NULL, NULL)){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							g_strfreev(tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else{
 | 
				
			||||||
 | 
							// there is only a number, or an empty string (e.g. in the case of "::")
 | 
				
			||||||
 | 
							if(g_strcmp0("", lastpart) && !g_ascii_string_to_unsigned(lastpart, 16, 0, 65536, NULL, NULL)){
 | 
				
			||||||
 | 
								success = FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ip6end:
 | 
				
			||||||
 | 
						g_strfreev(parts);
 | 
				
			||||||
 | 
						return success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -26,7 +26,11 @@
 | 
				
			|||||||
#define NMV_WG_TAG_PRIVATE_KEY			"PrivateKey"
 | 
					#define NMV_WG_TAG_PRIVATE_KEY			"PrivateKey"
 | 
				
			||||||
#define NMV_WG_TAG_LISTEN_PORT			"ListenPort"
 | 
					#define NMV_WG_TAG_LISTEN_PORT			"ListenPort"
 | 
				
			||||||
#define NMV_WG_TAG_ADDRESS				"Address"
 | 
					#define NMV_WG_TAG_ADDRESS				"Address"
 | 
				
			||||||
 | 
					#define NMV_WG_TAG_DNS                  "DNS"
 | 
				
			||||||
 | 
					#define NMV_WG_TAG_MTU                  "MTU"
 | 
				
			||||||
 | 
					#define NMV_WG_TAG_PRE_UP               "PreUp"
 | 
				
			||||||
#define NMV_WG_TAG_POST_UP				"PostUp"
 | 
					#define NMV_WG_TAG_POST_UP				"PostUp"
 | 
				
			||||||
 | 
					#define NMV_WG_TAG_PRE_DOWN             "PreDown"
 | 
				
			||||||
#define NMV_WG_TAG_POST_DOWN			"PostDown"
 | 
					#define NMV_WG_TAG_POST_DOWN			"PostDown"
 | 
				
			||||||
#define NMV_WG_TAG_PRESHARED_KEY		"PresharedKey"
 | 
					#define NMV_WG_TAG_PRESHARED_KEY		"PresharedKey"
 | 
				
			||||||
#define NMV_WG_TAG_PEER					"[Peer]"
 | 
					#define NMV_WG_TAG_PEER					"[Peer]"
 | 
				
			||||||
@ -92,6 +96,10 @@ gboolean is_pkcs12 (const char *filepath);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
gboolean is_encrypted (const char *filename);
 | 
					gboolean is_encrypted (const char *filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean is_ip4 (char *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean is_ip6 (char *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NMOVPN_PROTCOL_TYPES \
 | 
					#define NMOVPN_PROTCOL_TYPES \
 | 
				
			||||||
	"udp", \
 | 
						"udp", \
 | 
				
			||||||
	"udp4", \
 | 
						"udp4", \
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user