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).
pull/4/head
Max Moser 2018-04-05 13:58:07 +02:00
parent dce4fd41dd
commit 2470f6ad1f
5 changed files with 121 additions and 71 deletions

View File

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

View File

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

View File

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

View File

@ -544,4 +544,38 @@ gboolean is_fqdn(char *addr)
fqdn_end: 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;
} }

View File

@ -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", \