Fix issue with PSK and add checks for Base64 keys
Write PresharedKey to [Peer] section instead of [Interface] on export, as it should be. Change ConnectionEditor UI accordingly to reflect this change. Add check for proper length and Base64 encoding of keys (public, private, PSK).
This commit is contained in:
		
							parent
							
								
									dce4fd41dd
								
							
						
					
					
						commit
						2470f6ad1f
					
				@ -1,5 +1,5 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<!-- Generated with glade 3.20.2 -->
 | 
					<!-- Generated with glade 3.22.1 -->
 | 
				
			||||||
<interface>
 | 
					<interface>
 | 
				
			||||||
  <requires lib="gtk+" version="3.4"/>
 | 
					  <requires lib="gtk+" version="3.4"/>
 | 
				
			||||||
  <object class="GtkAdjustment" id="adjustment1">
 | 
					  <object class="GtkAdjustment" id="adjustment1">
 | 
				
			||||||
@ -203,6 +203,9 @@
 | 
				
			|||||||
    <property name="icon_name">stock-preferences</property>
 | 
					    <property name="icon_name">stock-preferences</property>
 | 
				
			||||||
    <property name="type_hint">dialog</property>
 | 
					    <property name="type_hint">dialog</property>
 | 
				
			||||||
    <property name="skip_pager_hint">True</property>
 | 
					    <property name="skip_pager_hint">True</property>
 | 
				
			||||||
 | 
					    <child>
 | 
				
			||||||
 | 
					      <placeholder/>
 | 
				
			||||||
 | 
					    </child>
 | 
				
			||||||
    <child internal-child="vbox">
 | 
					    <child internal-child="vbox">
 | 
				
			||||||
      <object class="GtkBox" id="dialog-vbox1">
 | 
					      <object class="GtkBox" id="dialog-vbox1">
 | 
				
			||||||
        <property name="visible">True</property>
 | 
					        <property name="visible">True</property>
 | 
				
			||||||
@ -1720,9 +1723,6 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
      <action-widget response="-6">cancel_button</action-widget>
 | 
					      <action-widget response="-6">cancel_button</action-widget>
 | 
				
			||||||
      <action-widget response="-5">ok_button</action-widget>
 | 
					      <action-widget response="-5">ok_button</action-widget>
 | 
				
			||||||
    </action-widgets>
 | 
					    </action-widgets>
 | 
				
			||||||
    <child>
 | 
					 | 
				
			||||||
      <placeholder/>
 | 
					 | 
				
			||||||
    </child>
 | 
					 | 
				
			||||||
  </object>
 | 
					  </object>
 | 
				
			||||||
  <object class="GtkBox" id="wg-vbox">
 | 
					  <object class="GtkBox" id="wg-vbox">
 | 
				
			||||||
    <property name="visible">True</property>
 | 
					    <property name="visible">True</property>
 | 
				
			||||||
@ -1896,45 +1896,6 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
            <property name="position">4</property>
 | 
					            <property name="position">4</property>
 | 
				
			||||||
          </packing>
 | 
					          </packing>
 | 
				
			||||||
        </child>
 | 
					        </child>
 | 
				
			||||||
        <child>
 | 
					 | 
				
			||||||
          <object class="GtkBox" id="preshared-key">
 | 
					 | 
				
			||||||
            <property name="visible">True</property>
 | 
					 | 
				
			||||||
            <property name="can_focus">False</property>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
              <object class="GtkLabel">
 | 
					 | 
				
			||||||
                <property name="visible">True</property>
 | 
					 | 
				
			||||||
                <property name="can_focus">False</property>
 | 
					 | 
				
			||||||
                <property name="label" translatable="yes">Preshared Key:</property>
 | 
					 | 
				
			||||||
                <property name="width_chars">15</property>
 | 
					 | 
				
			||||||
                <property name="max_width_chars">15</property>
 | 
					 | 
				
			||||||
                <attributes>
 | 
					 | 
				
			||||||
                  <attribute name="underline" value="True"/>
 | 
					 | 
				
			||||||
                </attributes>
 | 
					 | 
				
			||||||
              </object>
 | 
					 | 
				
			||||||
              <packing>
 | 
					 | 
				
			||||||
                <property name="expand">False</property>
 | 
					 | 
				
			||||||
                <property name="fill">False</property>
 | 
					 | 
				
			||||||
                <property name="position">0</property>
 | 
					 | 
				
			||||||
              </packing>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
            <child>
 | 
					 | 
				
			||||||
              <object class="GtkEntry" id="interface_psk_entry">
 | 
					 | 
				
			||||||
                <property name="visible">True</property>
 | 
					 | 
				
			||||||
                <property name="can_focus">True</property>
 | 
					 | 
				
			||||||
              </object>
 | 
					 | 
				
			||||||
              <packing>
 | 
					 | 
				
			||||||
                <property name="expand">True</property>
 | 
					 | 
				
			||||||
                <property name="fill">True</property>
 | 
					 | 
				
			||||||
                <property name="position">1</property>
 | 
					 | 
				
			||||||
              </packing>
 | 
					 | 
				
			||||||
            </child>
 | 
					 | 
				
			||||||
          </object>
 | 
					 | 
				
			||||||
          <packing>
 | 
					 | 
				
			||||||
            <property name="expand">False</property>
 | 
					 | 
				
			||||||
            <property name="fill">True</property>
 | 
					 | 
				
			||||||
            <property name="position">5</property>
 | 
					 | 
				
			||||||
          </packing>
 | 
					 | 
				
			||||||
        </child>
 | 
					 | 
				
			||||||
        <child>
 | 
					        <child>
 | 
				
			||||||
          <object class="GtkBox" id="dns">
 | 
					          <object class="GtkBox" id="dns">
 | 
				
			||||||
            <property name="visible">True</property>
 | 
					            <property name="visible">True</property>
 | 
				
			||||||
@ -2199,7 +2160,7 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
          </packing>
 | 
					          </packing>
 | 
				
			||||||
        </child>
 | 
					        </child>
 | 
				
			||||||
        <child>
 | 
					        <child>
 | 
				
			||||||
          <object class="GtkBox" id="Address1">
 | 
					          <object class="GtkBox" id="public-key">
 | 
				
			||||||
            <property name="visible">True</property>
 | 
					            <property name="visible">True</property>
 | 
				
			||||||
            <property name="can_focus">False</property>
 | 
					            <property name="can_focus">False</property>
 | 
				
			||||||
            <child>
 | 
					            <child>
 | 
				
			||||||
@ -2235,7 +2196,7 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
          </packing>
 | 
					          </packing>
 | 
				
			||||||
        </child>
 | 
					        </child>
 | 
				
			||||||
        <child>
 | 
					        <child>
 | 
				
			||||||
          <object class="GtkBox" id="Address3">
 | 
					          <object class="GtkBox" id="allowed-ips">
 | 
				
			||||||
            <property name="visible">True</property>
 | 
					            <property name="visible">True</property>
 | 
				
			||||||
            <property name="can_focus">False</property>
 | 
					            <property name="can_focus">False</property>
 | 
				
			||||||
            <child>
 | 
					            <child>
 | 
				
			||||||
@ -2271,7 +2232,7 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
          </packing>
 | 
					          </packing>
 | 
				
			||||||
        </child>
 | 
					        </child>
 | 
				
			||||||
        <child>
 | 
					        <child>
 | 
				
			||||||
          <object class="GtkBox" id="Address2">
 | 
					          <object class="GtkBox" id="endpoint">
 | 
				
			||||||
            <property name="visible">True</property>
 | 
					            <property name="visible">True</property>
 | 
				
			||||||
            <property name="can_focus">False</property>
 | 
					            <property name="can_focus">False</property>
 | 
				
			||||||
            <child>
 | 
					            <child>
 | 
				
			||||||
@ -2306,6 +2267,45 @@ config: http-proxy-retry or socks-proxy-retry</property>
 | 
				
			|||||||
            <property name="position">3</property>
 | 
					            <property name="position">3</property>
 | 
				
			||||||
          </packing>
 | 
					          </packing>
 | 
				
			||||||
        </child>
 | 
					        </child>
 | 
				
			||||||
 | 
					        <child>
 | 
				
			||||||
 | 
					          <object class="GtkBox" id="preshared-key">
 | 
				
			||||||
 | 
					            <property name="visible">True</property>
 | 
				
			||||||
 | 
					            <property name="can_focus">False</property>
 | 
				
			||||||
 | 
					            <child>
 | 
				
			||||||
 | 
					              <object class="GtkLabel">
 | 
				
			||||||
 | 
					                <property name="visible">True</property>
 | 
				
			||||||
 | 
					                <property name="can_focus">False</property>
 | 
				
			||||||
 | 
					                <property name="label" translatable="yes">Preshared Key:</property>
 | 
				
			||||||
 | 
					                <property name="width_chars">15</property>
 | 
				
			||||||
 | 
					                <property name="max_width_chars">15</property>
 | 
				
			||||||
 | 
					                <attributes>
 | 
				
			||||||
 | 
					                  <attribute name="underline" value="True"/>
 | 
				
			||||||
 | 
					                </attributes>
 | 
				
			||||||
 | 
					              </object>
 | 
				
			||||||
 | 
					              <packing>
 | 
				
			||||||
 | 
					                <property name="expand">False</property>
 | 
				
			||||||
 | 
					                <property name="fill">False</property>
 | 
				
			||||||
 | 
					                <property name="position">0</property>
 | 
				
			||||||
 | 
					              </packing>
 | 
				
			||||||
 | 
					            </child>
 | 
				
			||||||
 | 
					            <child>
 | 
				
			||||||
 | 
					              <object class="GtkEntry" id="peer_psk_entry">
 | 
				
			||||||
 | 
					                <property name="visible">True</property>
 | 
				
			||||||
 | 
					                <property name="can_focus">True</property>
 | 
				
			||||||
 | 
					              </object>
 | 
				
			||||||
 | 
					              <packing>
 | 
				
			||||||
 | 
					                <property name="expand">True</property>
 | 
				
			||||||
 | 
					                <property name="fill">True</property>
 | 
				
			||||||
 | 
					                <property name="position">1</property>
 | 
				
			||||||
 | 
					              </packing>
 | 
				
			||||||
 | 
					            </child>
 | 
				
			||||||
 | 
					          </object>
 | 
				
			||||||
 | 
					          <packing>
 | 
				
			||||||
 | 
					            <property name="expand">False</property>
 | 
				
			||||||
 | 
					            <property name="fill">True</property>
 | 
				
			||||||
 | 
					            <property name="position">4</property>
 | 
				
			||||||
 | 
					          </packing>
 | 
				
			||||||
 | 
					        </child>
 | 
				
			||||||
      </object>
 | 
					      </object>
 | 
				
			||||||
      <packing>
 | 
					      <packing>
 | 
				
			||||||
        <property name="expand">False</property>
 | 
					        <property name="expand">False</property>
 | 
				
			||||||
 | 
				
			|||||||
@ -99,14 +99,29 @@ check_interface_mtu_entry(const char *str)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
check_interface_private_key(const char *str)
 | 
					check_peer_preshared_key(const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if(is_empty(str)){
 | 
						if(is_empty(str)){
 | 
				
			||||||
 | 
							return TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// WireGuard has Base64-encoded PSKs of length 44
 | 
				
			||||||
 | 
						if(strlen(str) != 44){
 | 
				
			||||||
		return FALSE;
 | 
							return FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO maybe check length, base64 encoding, ...?
 | 
						return is_base64((char *)str);
 | 
				
			||||||
	return TRUE;
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					check_interface_private_key(const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return check_peer_preshared_key(str);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					check_peer_public_key(const char *str){
 | 
				
			||||||
 | 
						return check_peer_preshared_key(str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
@ -119,11 +134,6 @@ check_interface_listen_port(const char *str)
 | 
				
			|||||||
	return TRUE;
 | 
						return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					 | 
				
			||||||
check_peer_public_key(const char *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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -254,6 +264,9 @@ check_validity (WireguardEditor *self, GError **error)
 | 
				
			|||||||
	if(!check(priv, "peer_endpoint_entry", check_peer_endpoint, NM_WG_KEY_ENDPOINT, TRUE, error)){
 | 
						if(!check(priv, "peer_endpoint_entry", check_peer_endpoint, NM_WG_KEY_ENDPOINT, TRUE, error)){
 | 
				
			||||||
		success = FALSE;
 | 
							success = FALSE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if(!check(priv, "peer_psk_entry", check_peer_preshared_key, NM_WG_KEY_PRESHARED_KEY, TRUE, error)){
 | 
				
			||||||
 | 
							success = FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// pre-up, post-up, pre-down, post-down are scripts and don't get validated
 | 
						// pre-up, post-up, pre-down, post-down are scripts and don't get validated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(ip4_ok && ip6_ok){
 | 
						if(ip4_ok && ip6_ok){
 | 
				
			||||||
@ -415,7 +428,7 @@ init_editor_plugin (WireguardEditor *self, NMConnection *connection, GError **er
 | 
				
			|||||||
	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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Interface Preshared Key
 | 
						// Interface Preshared Key
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_psk_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_psk_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_PRESHARED_KEY);
 | 
							value = nm_setting_vpn_get_data_item (s_vpn, NM_WG_KEY_PRESHARED_KEY);
 | 
				
			||||||
@ -561,7 +574,7 @@ update_connection (NMVpnEditor *iface,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// preshared key
 | 
						// preshared key
 | 
				
			||||||
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_psk_entry"));
 | 
						widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "peer_psk_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_PRESHARED_KEY, str);
 | 
							nm_setting_vpn_add_data_item (s_vpn, NM_WG_KEY_PRESHARED_KEY, str);
 | 
				
			||||||
 | 
				
			|||||||
@ -892,17 +892,6 @@ do_import (const char *path, const char *contents, gsize contents_len, GError **
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (NM_IN_STRSET (params[0], NMV_WG_TAG_PRESHARED_KEY)){
 | 
					 | 
				
			||||||
			char *psk = NULL;
 | 
					 | 
				
			||||||
			if(!parse_preshared_key(params, &psk, &line_error)){
 | 
					 | 
				
			||||||
				goto handle_line_error;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			setting_vpn_add_data_item(s_vpn, NM_WG_KEY_PRESHARED_KEY, psk);
 | 
					 | 
				
			||||||
			printf("%s = %s\n", NMV_WG_TAG_PRESHARED_KEY, psk);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (NM_IN_STRSET (params[0], NMV_WG_TAG_PRE_UP)){
 | 
							if (NM_IN_STRSET (params[0], NMV_WG_TAG_PRE_UP)){
 | 
				
			||||||
			char *script = NULL;
 | 
								char *script = NULL;
 | 
				
			||||||
			if(!parse_script(params, &script, &line_error)){
 | 
								if(!parse_script(params, &script, &line_error)){
 | 
				
			||||||
@ -1006,6 +995,17 @@ do_import (const char *path, const char *contents, gsize contents_len, GError **
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (NM_IN_STRSET (params[0], NMV_WG_TAG_PRESHARED_KEY)){
 | 
				
			||||||
 | 
								char *psk = NULL;
 | 
				
			||||||
 | 
								if(!parse_preshared_key(params, &psk, &line_error)){
 | 
				
			||||||
 | 
									goto handle_line_error;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								setting_vpn_add_data_item(s_vpn, NM_WG_KEY_PRESHARED_KEY, psk);
 | 
				
			||||||
 | 
								printf("%s = %s\n", NMV_WG_TAG_PRESHARED_KEY, psk);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* currently we ignore any unknown options and skip over them. */
 | 
							/* currently we ignore any unknown options and skip over them. */
 | 
				
			||||||
		continue;
 | 
							continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1208,9 +1208,6 @@ create_config_string (NMConnection *connection, GError **error)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	args_write_line(f, NMV_WG_TAG_LISTEN_PORT, "=", listen_port);
 | 
						args_write_line(f, NMV_WG_TAG_LISTEN_PORT, "=", listen_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(psk){
 | 
					 | 
				
			||||||
		args_write_line(f, NMV_WG_TAG_PRESHARED_KEY, "=", psk);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if(post_up){
 | 
						if(post_up){
 | 
				
			||||||
		args_write_line(f, NMV_WG_TAG_POST_UP, "=", post_up);
 | 
							args_write_line(f, NMV_WG_TAG_POST_UP, "=", post_up);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -1233,6 +1230,10 @@ create_config_string (NMConnection *connection, GError **error)
 | 
				
			|||||||
	g_strfreev (ip_list);
 | 
						g_strfreev (ip_list);
 | 
				
			||||||
	g_array_free(ips, TRUE);
 | 
						g_array_free(ips, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(psk){
 | 
				
			||||||
 | 
							args_write_line(f, NMV_WG_TAG_PRESHARED_KEY, "=", psk);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return g_steal_pointer (&f);
 | 
						return g_steal_pointer (&f);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -545,3 +545,37 @@ fqdn_end:
 | 
				
			|||||||
	g_strfreev(parts);
 | 
						g_strfreev(parts);
 | 
				
			||||||
	return success;
 | 
						return success;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean is_base64(char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *ptr = str;
 | 
				
			||||||
 | 
						int padding = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Base64 only allows for alphanumeric characters along with
 | 
				
			||||||
 | 
						// '+', '/' (and '=' as trailing padding)
 | 
				
			||||||
 | 
						for(; ptr && *ptr; ptr++){
 | 
				
			||||||
 | 
							if(*ptr == '='){
 | 
				
			||||||
 | 
								padding++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(padding <= 0){
 | 
				
			||||||
 | 
								if(!g_ascii_isalnum(*ptr) &&
 | 
				
			||||||
 | 
									(*ptr != '+') &&
 | 
				
			||||||
 | 
									(*ptr != '/')){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return FALSE;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								if(*ptr != '='){
 | 
				
			||||||
 | 
									return FALSE;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if we have more than 3x '=', there's too much padding
 | 
				
			||||||
 | 
						if(padding > 3){
 | 
				
			||||||
 | 
							return FALSE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -104,6 +104,8 @@ gboolean is_ip6 (char *addr);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
gboolean is_fqdn(char *addr);
 | 
					gboolean is_fqdn(char *addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean is_base64(char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NMOVPN_PROTCOL_TYPES \
 | 
					#define NMOVPN_PROTCOL_TYPES \
 | 
				
			||||||
	"udp", \
 | 
						"udp", \
 | 
				
			||||||
	"udp4", \
 | 
						"udp4", \
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user