Implement import/export and connection editor UI

pull/1/head
Max Moser 2018-02-11 17:29:38 +01:00
parent 3209433372
commit 94046d0b8c
4 changed files with 743 additions and 1734 deletions

File diff suppressed because it is too large Load Diff

View File

@ -65,30 +65,56 @@ typedef struct {
#define COL_AUTH_PAGE 1
#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
check_interface_ip4_entry(const char *str)
{
gs_free char *str_clone = NULL;
char *str_iter;
const char *tok;
int count = 0;
return is_ip4((char *)str);
}
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;
}
}
str_clone = g_strdup(str);
str_iter = str_clone;
while((tok = strsep(&str_iter, "."))){
count ++;
// each number in an IP4 must be: 0 <= X <= 255
if(!g_ascii_string_to_unsigned(tok, 10, 0, 255, NULL, NULL)){
return FALSE;
static gboolean
check_interface_mtu_entry(const char *str)
{
if(is_empty(str)){
return TRUE;
}
}
// an IP4 consists of 4 segments
if(count != 4){
else if(!g_ascii_string_to_unsigned(str, 10, 0, 1500, NULL, NULL)){
return FALSE;
}
@ -98,11 +124,7 @@ check_interface_ip4_entry(const char *str)
static gboolean
check_interface_private_key(const char *str)
{
gs_free char *str_clone = NULL;
str_clone = g_strdup(str);
str_clone = g_strstrip(str_clone);
if(!g_strcmp0("", str_clone)){
if(is_empty(str)){
return FALSE;
}
@ -113,10 +135,7 @@ check_interface_private_key(const char *str)
static gboolean
check_interface_listen_port(const char *str)
{
gs_free char *str_clone = NULL;
str_clone = g_strdup(str);
if(!g_ascii_string_to_unsigned(str_clone, 10, 0, 65535, NULL, NULL)){
if(!g_ascii_string_to_unsigned(str, 10, 0, 65535, NULL, NULL)){
return FALSE;
}
@ -124,58 +143,54 @@ check_interface_listen_port(const char *str)
}
static gboolean
check_peer_public_key(const char *str)
{
// TODO
check_peer_public_key(const char *str){
return check_interface_private_key(str);
}
static gboolean
check_peer_allowed_ips(const char *str)
{
// TODO
return check_interface_ip4_entry(str);
gchar **ips;
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
check_peer_endpoint(const char *str)
{
// TODO
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;
return is_ip4((char *)str) || is_ip6((char *)str);
}
typedef gboolean (*CheckFunc)(const char *str);
// helper function to reduce boilerplate code in 'check_validity()'
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;
GtkWidget *widget;
@ -186,11 +201,11 @@ check (OpenvpnEditorPrivate *priv, char *widget_name, CheckFunc chk, GError **er
else {
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error");
// only set the error if it's NULL
if(error == NULL){
if(error == NULL && set_error){
g_set_error (error,
NMV_EDITOR_PLUGIN_ERROR,
NMV_EDITOR_PLUGIN_ERROR_INVALID_PROPERTY,
NM_WG_KEY_ADDR_IP4);
key);
}
return FALSE;
}
@ -198,6 +213,28 @@ check (OpenvpnEditorPrivate *priv, char *widget_name, CheckFunc chk, GError **er
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
check_validity (OpenvpnEditor *self, GError **error)
{
@ -206,27 +243,73 @@ check_validity (OpenvpnEditor *self, GError **error)
GtkTreeModel *model;
GtkTreeIter iter;
const char *contype = NULL;
gboolean success;
gboolean success = TRUE;
gboolean ip4_ok = TRUE;
gboolean ip6_ok = TRUE;
// 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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"));
@ -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);
// 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
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_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_IP4);
value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRIVATE_KEY);
if (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"));
g_return_val_if_fail (widget != NULL, FALSE);
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)
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"));
g_return_val_if_fail (widget != NULL, FALSE);
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)
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"));
g_return_val_if_fail (widget != NULL, FALSE);
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)
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"));
g_return_val_if_fail (widget != NULL, FALSE);
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)
gtk_entry_set_text (GTK_ENTRY (widget), value);
}
@ -576,18 +739,66 @@ update_connection (NMVpnEditor *iface,
if (str && str[0])
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
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_private_key_entry"));
str = gtk_entry_get_text (GTK_ENTRY (widget));
if (str && str[0])
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
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_port_entry"));
str = gtk_entry_get_text (GTK_ENTRY (widget));
if (str && str[0])
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
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_public_key_entry"));
str = gtk_entry_get_text (GTK_ENTRY (widget));

View File

@ -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;
}

View File

@ -26,7 +26,11 @@
#define NMV_WG_TAG_PRIVATE_KEY "PrivateKey"
#define NMV_WG_TAG_LISTEN_PORT "ListenPort"
#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_PRE_DOWN "PreDown"
#define NMV_WG_TAG_POST_DOWN "PostDown"
#define NMV_WG_TAG_PRESHARED_KEY "PresharedKey"
#define NMV_WG_TAG_PEER "[Peer]"
@ -92,6 +96,10 @@ gboolean is_pkcs12 (const char *filepath);
gboolean is_encrypted (const char *filename);
gboolean is_ip4 (char *addr);
gboolean is_ip6 (char *addr);
#define NMOVPN_PROTCOL_TYPES \
"udp", \
"udp4", \