2012-12-09 19:38:32 -05:00
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams < dcbw @ redhat . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
2016-06-07 12:03:22 +02:00
* Copyright 2007 - 2014 Red Hat , Inc .
2012-12-09 19:38:32 -05:00
*/
2019-11-12 09:53:18 +13:00
# include <glib/gi18n.h>
2012-12-09 19:38:32 -05:00
2014-08-13 13:43:40 +02:00
# include "helpers.h"
2016-06-07 12:03:22 +02:00
# include "nma-ui-utils.h"
2019-11-12 10:08:14 +13:00
# include "ui-helpers.h"
# include "ws-wep-key.h"
# include "wireless-security.h"
2012-12-09 19:38:32 -05:00
struct _WirelessSecurityWEPKey {
2019-12-03 09:47:46 +13:00
GtkGrid parent ;
2012-12-09 19:38:32 -05:00
2019-10-15 12:25:48 +13:00
GtkComboBox * auth_method_combo ;
GtkLabel * auth_method_label ;
GtkEntry * key_entry ;
GtkComboBox * key_index_combo ;
GtkLabel * key_index_label ;
GtkLabel * key_label ;
GtkCheckButton * show_key_check ;
2012-12-09 19:38:32 -05:00
NMWepKeyType type ;
char keys [ 4 ] [ 65 ] ;
guint8 cur_index ;
} ;
2019-12-03 09:27:03 +13:00
static void wireless_security_iface_init ( WirelessSecurityInterface * ) ;
2019-12-03 09:47:46 +13:00
G_DEFINE_TYPE_WITH_CODE ( WirelessSecurityWEPKey , ws_wep_key , GTK_TYPE_GRID ,
2019-12-03 09:27:03 +13:00
G_IMPLEMENT_INTERFACE ( wireless_security_get_type ( ) , wireless_security_iface_init ) ) ;
2019-11-07 12:37:34 +13:00
2012-12-09 19:38:32 -05:00
static void
2019-10-15 11:15:30 +13:00
show_toggled_cb ( WirelessSecurityWEPKey * self )
2012-12-09 19:38:32 -05:00
{
gboolean visible ;
2019-10-15 12:25:48 +13:00
visible = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( self - > show_key_check ) ) ;
gtk_entry_set_visibility ( self - > key_entry , visible ) ;
2012-12-09 19:38:32 -05:00
}
static void
2019-10-15 11:15:30 +13:00
key_index_combo_changed_cb ( WirelessSecurityWEPKey * self )
2012-12-09 19:38:32 -05:00
{
const char * key ;
int key_index ;
/* Save WEP key for old key index */
2019-10-15 12:25:48 +13:00
key = gtk_entry_get_text ( self - > key_entry ) ;
2012-12-09 19:38:32 -05:00
if ( key )
2019-10-15 11:15:30 +13:00
g_strlcpy ( self - > keys [ self - > cur_index ] , key , sizeof ( self - > keys [ self - > cur_index ] ) ) ;
2012-12-09 19:38:32 -05:00
else
2019-10-15 11:15:30 +13:00
memset ( self - > keys [ self - > cur_index ] , 0 , sizeof ( self - > keys [ self - > cur_index ] ) ) ;
2012-12-09 19:38:32 -05:00
2019-10-15 12:25:48 +13:00
key_index = gtk_combo_box_get_active ( self - > key_index_combo ) ;
2012-12-09 19:38:32 -05:00
g_return_if_fail ( key_index < = 3 ) ;
g_return_if_fail ( key_index > = 0 ) ;
/* Populate entry with key from new index */
2019-10-15 12:25:48 +13:00
gtk_entry_set_text ( self - > key_entry , self - > keys [ key_index ] ) ;
2019-10-15 11:15:30 +13:00
self - > cur_index = key_index ;
2012-12-09 19:38:32 -05:00
2019-10-15 12:25:48 +13:00
wireless_security_notify_changed ( ( WirelessSecurity * ) self ) ;
2012-12-09 19:38:32 -05:00
}
static void
2019-11-07 12:37:34 +13:00
ws_wep_key_dispose ( GObject * object )
2012-12-09 19:38:32 -05:00
{
2019-11-07 12:37:34 +13:00
WirelessSecurityWEPKey * self = WS_WEP_KEY ( object ) ;
2012-12-09 19:38:32 -05:00
int i ;
for ( i = 0 ; i < 4 ; i + + )
2019-10-18 11:47:17 +13:00
memset ( self - > keys [ i ] , 0 , sizeof ( self - > keys [ i ] ) ) ;
2019-11-07 12:37:34 +13:00
G_OBJECT_CLASS ( ws_wep_key_parent_class ) - > dispose ( object ) ;
2012-12-09 19:38:32 -05:00
}
static gboolean
2019-11-07 12:37:34 +13:00
validate ( WirelessSecurity * security , GError * * error )
2012-12-09 19:38:32 -05:00
{
2019-11-07 12:37:34 +13:00
WirelessSecurityWEPKey * self = WS_WEP_KEY ( security ) ;
2012-12-09 19:38:32 -05:00
const char * key ;
int i ;
2019-10-18 11:47:17 +13:00
key = gtk_entry_get_text ( self - > key_entry ) ;
2014-08-07 18:32:34 +02:00
if ( ! key ) {
2019-10-18 11:47:17 +13:00
widget_set_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
g_set_error_literal ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " missing wep-key " ) ) ;
2012-12-09 19:38:32 -05:00
return FALSE ;
2014-08-07 18:32:34 +02:00
}
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
if ( self - > type = = NM_WEP_KEY_TYPE_KEY ) {
2012-12-09 19:38:32 -05:00
if ( ( strlen ( key ) = = 10 ) | | ( strlen ( key ) = = 26 ) ) {
for ( i = 0 ; i < strlen ( key ) ; i + + ) {
2016-06-07 12:03:22 +02:00
if ( ! g_ascii_isxdigit ( key [ i ] ) ) {
2019-10-18 11:47:17 +13:00
widget_set_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
g_set_error ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " invalid wep-key: key with a length of %zu must contain only hex-digits " ) , strlen ( key ) ) ;
2012-12-09 19:38:32 -05:00
return FALSE ;
2014-08-07 18:32:34 +02:00
}
2012-12-09 19:38:32 -05:00
}
} else if ( ( strlen ( key ) = = 5 ) | | ( strlen ( key ) = = 13 ) ) {
for ( i = 0 ; i < strlen ( key ) ; i + + ) {
2019-10-15 11:23:20 +13:00
if ( ! g_ascii_isprint ( key [ i ] ) ) {
2019-10-18 11:47:17 +13:00
widget_set_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
g_set_error ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " invalid wep-key: key with a length of %zu must contain only ascii characters " ) , strlen ( key ) ) ;
2012-12-09 19:38:32 -05:00
return FALSE ;
2014-08-07 18:32:34 +02:00
}
2012-12-09 19:38:32 -05:00
}
} else {
2019-10-18 11:47:17 +13:00
widget_set_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
g_set_error ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " invalid wep-key: wrong key length %zu. A key must be either of length 5/13 (ascii) or 10/26 (hex) " ) , strlen ( key ) ) ;
2012-12-09 19:38:32 -05:00
return FALSE ;
}
2019-10-18 11:47:17 +13:00
} else if ( self - > type = = NM_WEP_KEY_TYPE_PASSPHRASE ) {
2016-06-07 12:03:22 +02:00
if ( ! * key | | ( strlen ( key ) > 64 ) ) {
2019-10-18 11:47:17 +13:00
widget_set_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
if ( ! * key )
g_set_error_literal ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " invalid wep-key: passphrase must be non-empty " ) ) ;
else
g_set_error_literal ( error , NMA_ERROR , NMA_ERROR_GENERIC , _ ( " invalid wep-key: passphrase must be shorter than 64 characters " ) ) ;
2012-12-09 19:38:32 -05:00
return FALSE ;
2014-08-07 18:32:34 +02:00
}
2012-12-09 19:38:32 -05:00
}
2019-10-18 11:47:17 +13:00
widget_unset_error ( GTK_WIDGET ( self - > key_entry ) ) ;
2012-12-09 19:38:32 -05:00
return TRUE ;
}
static void
2019-11-07 12:37:34 +13:00
add_to_size_group ( WirelessSecurity * security , GtkSizeGroup * group )
2012-12-09 19:38:32 -05:00
{
2019-11-07 12:37:34 +13:00
WirelessSecurityWEPKey * self = WS_WEP_KEY ( security ) ;
2019-10-15 12:25:48 +13:00
gtk_size_group_add_widget ( group , GTK_WIDGET ( self - > auth_method_label ) ) ;
gtk_size_group_add_widget ( group , GTK_WIDGET ( self - > key_label ) ) ;
gtk_size_group_add_widget ( group , GTK_WIDGET ( self - > key_index_label ) ) ;
2012-12-09 19:38:32 -05:00
}
static void
2019-11-07 12:37:34 +13:00
fill_connection ( WirelessSecurity * security , NMConnection * connection )
2012-12-09 19:38:32 -05:00
{
2019-11-07 12:37:34 +13:00
WirelessSecurityWEPKey * self = WS_WEP_KEY ( security ) ;
2012-12-09 19:38:32 -05:00
NMSettingWirelessSecurity * s_wsec ;
2016-06-07 12:03:22 +02:00
NMSettingSecretFlags secret_flags ;
2012-12-09 19:38:32 -05:00
gint auth_alg ;
const char * key ;
int i ;
2019-10-18 11:47:17 +13:00
auth_alg = gtk_combo_box_get_active ( self - > auth_method_combo ) ;
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
key = gtk_entry_get_text ( self - > key_entry ) ;
g_strlcpy ( self - > keys [ self - > cur_index ] , key , sizeof ( self - > keys [ self - > cur_index ] ) ) ;
2012-12-09 19:38:32 -05:00
/* Blow away the old security setting by adding a clear one */
s_wsec = ( NMSettingWirelessSecurity * ) nm_setting_wireless_security_new ( ) ;
nm_connection_add_setting ( connection , ( NMSetting * ) s_wsec ) ;
g_object_set ( s_wsec ,
NM_SETTING_WIRELESS_SECURITY_KEY_MGMT , " none " ,
2019-10-18 11:47:17 +13:00
NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX , self - > cur_index ,
2012-12-09 19:38:32 -05:00
NM_SETTING_WIRELESS_SECURITY_AUTH_ALG , ( auth_alg = = 1 ) ? " shared " : " open " ,
2019-10-18 11:47:17 +13:00
NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE , self - > type ,
2012-12-09 19:38:32 -05:00
NULL ) ;
for ( i = 0 ; i < 4 ; i + + ) {
2019-10-18 11:47:17 +13:00
if ( strlen ( self - > keys [ i ] ) )
nm_setting_wireless_security_set_wep_key ( s_wsec , i , self - > keys [ i ] ) ;
2012-12-09 19:38:32 -05:00
}
2016-06-07 12:03:22 +02:00
/* Save WEP_KEY_FLAGS to the connection */
2019-10-18 11:47:17 +13:00
secret_flags = nma_utils_menu_to_secret_flags ( GTK_WIDGET ( self - > key_entry ) ) ;
2016-06-07 12:03:22 +02:00
g_object_set ( s_wsec , NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS , secret_flags , NULL ) ;
/* Update secret flags and popup when editing the connection */
2019-12-03 15:14:56 +13:00
nma_utils_update_password_storage ( GTK_WIDGET ( self - > key_entry ) , secret_flags ,
2019-12-03 15:18:11 +13:00
NM_SETTING ( s_wsec ) , NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 ) ;
2012-12-09 19:38:32 -05:00
}
static void
2019-10-15 11:15:30 +13:00
wep_entry_filter_cb ( WirelessSecurityWEPKey * self ,
2016-06-07 12:03:22 +02:00
gchar * text ,
gint length ,
2019-10-15 11:15:30 +13:00
gint * position )
2012-12-09 19:38:32 -05:00
{
2019-10-15 11:15:30 +13:00
if ( self - > type = = NM_WEP_KEY_TYPE_KEY ) {
2019-10-15 11:23:20 +13:00
int i , count = 0 ;
g_autofree gchar * result = g_new ( gchar , length + 1 ) ;
for ( i = 0 ; i < length ; i + + ) {
if ( g_ascii_isprint ( text [ i ] ) )
result [ count + + ] = text [ i ] ;
}
result [ count ] = 0 ;
if ( count > 0 ) {
2019-10-15 12:25:48 +13:00
g_signal_handlers_block_by_func ( self - > key_entry , G_CALLBACK ( wep_entry_filter_cb ) , self ) ;
gtk_editable_insert_text ( GTK_EDITABLE ( self - > key_entry ) , result , count , position ) ;
g_signal_handlers_unblock_by_func ( self - > key_entry , G_CALLBACK ( wep_entry_filter_cb ) , self ) ;
2019-10-15 11:23:20 +13:00
}
2019-10-15 12:25:48 +13:00
g_signal_stop_emission_by_name ( self - > key_entry , " insert-text " ) ;
2012-12-09 19:38:32 -05:00
}
}
static void
2019-11-07 12:37:34 +13:00
update_secrets ( WirelessSecurityWEPKey * self , NMConnection * connection )
2012-12-09 19:38:32 -05:00
{
NMSettingWirelessSecurity * s_wsec ;
const char * tmp ;
int i ;
s_wsec = nm_connection_get_setting_wireless_security ( connection ) ;
for ( i = 0 ; s_wsec & & i < 4 ; i + + ) {
tmp = nm_setting_wireless_security_get_wep_key ( s_wsec , i ) ;
if ( tmp )
2019-10-18 11:47:17 +13:00
g_strlcpy ( self - > keys [ i ] , tmp , sizeof ( self - > keys [ i ] ) ) ;
2012-12-09 19:38:32 -05:00
}
2019-10-18 11:47:17 +13:00
if ( strlen ( self - > keys [ self - > cur_index ] ) )
gtk_entry_set_text ( self - > key_entry , self - > keys [ self - > cur_index ] ) ;
2012-12-09 19:38:32 -05:00
}
2019-10-15 10:33:17 +13:00
static void
changed_cb ( WirelessSecurityWEPKey * self )
{
wireless_security_notify_changed ( ( WirelessSecurity * ) self ) ;
}
2019-11-07 12:37:34 +13:00
void
ws_wep_key_init ( WirelessSecurityWEPKey * self )
{
2019-12-03 09:47:46 +13:00
gtk_widget_init_template ( GTK_WIDGET ( self ) ) ;
2019-11-07 12:37:34 +13:00
}
void
ws_wep_key_class_init ( WirelessSecurityWEPKeyClass * klass )
{
GObjectClass * object_class = G_OBJECT_CLASS ( klass ) ;
2019-12-03 09:47:46 +13:00
GtkWidgetClass * widget_class = GTK_WIDGET_CLASS ( klass ) ;
2019-11-07 12:37:34 +13:00
object_class - > dispose = ws_wep_key_dispose ;
2019-12-03 09:47:46 +13:00
gtk_widget_class_set_template_from_resource ( widget_class , " /org/gnome/ControlCenter/network/ws-wep-key.ui " ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , auth_method_combo ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , auth_method_label ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , key_entry ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , key_index_combo ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , key_index_label ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , key_label ) ;
gtk_widget_class_bind_template_child ( widget_class , WirelessSecurityWEPKey , show_key_check ) ;
2019-12-03 09:27:03 +13:00
}
static void
wireless_security_iface_init ( WirelessSecurityInterface * iface )
{
iface - > validate = validate ;
iface - > add_to_size_group = add_to_size_group ;
iface - > fill_connection = fill_connection ;
2019-11-07 12:37:34 +13:00
}
2012-12-09 19:38:32 -05:00
WirelessSecurityWEPKey *
ws_wep_key_new ( NMConnection * connection ,
2019-12-03 15:14:56 +13:00
NMWepKeyType type )
2012-12-09 19:38:32 -05:00
{
2019-10-18 11:47:17 +13:00
WirelessSecurityWEPKey * self ;
2012-12-09 19:38:32 -05:00
NMSettingWirelessSecurity * s_wsec = NULL ;
2016-06-07 12:03:22 +02:00
NMSetting * setting = NULL ;
2012-12-09 19:38:32 -05:00
guint8 default_key_idx = 0 ;
2019-12-03 15:14:56 +13:00
gboolean is_adhoc = FALSE ;
2012-12-09 19:38:32 -05:00
gboolean is_shared_key = FALSE ;
2019-11-07 12:37:34 +13:00
self = g_object_new ( ws_wep_key_get_type ( ) , NULL ) ;
2019-10-15 12:25:48 +13:00
2019-10-18 11:47:17 +13:00
self - > type = type ;
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
gtk_entry_set_width_chars ( self - > key_entry , 28 ) ;
2012-12-09 19:38:32 -05:00
2016-06-07 12:03:22 +02:00
/* Create password-storage popup menu for password entry under entry's secondary icon */
if ( connection )
setting = ( NMSetting * ) nm_connection_get_setting_wireless_security ( connection ) ;
2019-12-03 15:18:11 +13:00
nma_utils_setup_password_storage ( GTK_WIDGET ( self - > key_entry ) , 0 , setting , NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 ,
2019-12-03 15:14:56 +13:00
FALSE , FALSE ) ;
2016-06-07 12:03:22 +02:00
2012-12-09 19:38:32 -05:00
if ( connection ) {
NMSettingWireless * s_wireless ;
const char * mode , * auth_alg ;
s_wireless = nm_connection_get_setting_wireless ( connection ) ;
mode = s_wireless ? nm_setting_wireless_get_mode ( s_wireless ) : NULL ;
if ( mode & & ! strcmp ( mode , " adhoc " ) )
is_adhoc = TRUE ;
s_wsec = nm_connection_get_setting_wireless_security ( connection ) ;
if ( s_wsec ) {
auth_alg = nm_setting_wireless_security_get_auth_alg ( s_wsec ) ;
if ( auth_alg & & ! strcmp ( auth_alg , " shared " ) )
is_shared_key = TRUE ;
}
}
2019-10-18 11:47:17 +13:00
g_signal_connect_swapped ( self - > key_entry , " changed " , G_CALLBACK ( changed_cb ) , self ) ;
g_signal_connect_swapped ( self - > key_entry , " insert-text " , G_CALLBACK ( wep_entry_filter_cb ) , self ) ;
if ( self - > type = = NM_WEP_KEY_TYPE_KEY )
gtk_entry_set_max_length ( self - > key_entry , 26 ) ;
else if ( self - > type = = NM_WEP_KEY_TYPE_PASSPHRASE )
gtk_entry_set_max_length ( self - > key_entry , 64 ) ;
2012-12-09 19:38:32 -05:00
if ( connection & & s_wsec )
default_key_idx = nm_setting_wireless_security_get_wep_tx_keyidx ( s_wsec ) ;
2019-10-18 11:47:17 +13:00
gtk_combo_box_set_active ( self - > key_index_combo , default_key_idx ) ;
self - > cur_index = default_key_idx ;
g_signal_connect_swapped ( self - > key_index_combo , " changed " , G_CALLBACK ( key_index_combo_changed_cb ) , self ) ;
2012-12-09 19:38:32 -05:00
/* Key index is useless with adhoc networks */
2019-12-03 15:14:56 +13:00
if ( is_adhoc ) {
2019-10-18 11:47:17 +13:00
gtk_widget_hide ( GTK_WIDGET ( self - > key_index_combo ) ) ;
gtk_widget_hide ( GTK_WIDGET ( self - > key_index_label ) ) ;
2012-12-09 19:38:32 -05:00
}
/* Fill the key entry with the key for that index */
if ( connection )
2019-11-07 12:37:34 +13:00
update_secrets ( self , connection ) ;
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
g_signal_connect_swapped ( self - > show_key_check , " toggled " , G_CALLBACK ( show_toggled_cb ) , self ) ;
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
gtk_combo_box_set_active ( self - > auth_method_combo , is_shared_key ? 1 : 0 ) ;
2012-12-09 19:38:32 -05:00
2019-10-18 11:47:17 +13:00
g_signal_connect_swapped ( self - > auth_method_combo , " changed " , G_CALLBACK ( changed_cb ) , self ) ;
2012-12-09 19:38:32 -05:00
/* Don't show auth method for adhoc (which always uses open-system) or
* when in " simple " mode .
*/
2019-12-03 15:14:56 +13:00
if ( is_adhoc ) {
2012-12-09 19:38:32 -05:00
/* Ad-Hoc connections can't use Shared Key auth */
if ( is_adhoc )
2019-10-18 11:47:17 +13:00
gtk_combo_box_set_active ( self - > auth_method_combo , 0 ) ;
gtk_widget_hide ( GTK_WIDGET ( self - > auth_method_combo ) ) ;
gtk_widget_hide ( GTK_WIDGET ( self - > auth_method_label ) ) ;
2012-12-09 19:38:32 -05:00
}
2019-10-18 11:47:17 +13:00
return self ;
2012-12-09 19:38:32 -05:00
}