Commit 5de8a032 authored by Tambet Ingo's avatar Tambet Ingo Committed by Tambet Ingo
Browse files

Rewrite the VPN connection handling now that everything underneath has

2007-09-12  Tambet Ingo  <tambet@gmail.com>

        * src/applet.c: Rewrite the VPN connection handling now that
        * everything
        underneath has changed.

        * src/vpn-properties/nm-vpn-ui-interface.h: Convert properties
        * to hash tables
        eveyrwhere.

        * src/vpn-properties/nm-vpn-properties.c: Create properties hash
        * tables instead
        of GSLists.

        * src/vpn-password-dialog.c: Passwords are now dictionary items.
        * Use odd strings
        from the helper output as keys, even keys for values.

        * src/vpn-connection-info.[ch]: Implement.


svn path=/trunk/; revision=150
parent 6ecdc13d
2007-09-12 Tambet Ingo <tambet@gmail.com>
* src/applet.c: Rewrite the VPN connection handling now that everything
underneath has changed.
* src/vpn-properties/nm-vpn-ui-interface.h: Convert properties to hash tables
eveyrwhere.
* src/vpn-properties/nm-vpn-properties.c: Create properties hash tables instead
of GSLists.
* src/vpn-password-dialog.c: Passwords are now dictionary items. Use odd strings
from the helper output as keys, even keys for values.
* src/vpn-connection-info.[ch]: Implement.
2007-09-11 Dan Williams <dcbw@redhat.com>
* src/applet-dbus-settings.c
......
......@@ -35,6 +35,8 @@ nm_applet_SOURCES = \
applet-dbus-settings.h \
menu-items.c \
menu-items.h \
vpn-connection-info.c \
vpn-connection-info.h \
vpn-password-dialog.c \
vpn-password-dialog.h \
gconf-helpers.c \
......
This diff is collapsed.
......@@ -43,6 +43,7 @@
#include <nm-client.h>
#include <nm-access-point.h>
#include <nm-vpn-manager.h>
#include <nm-device.h>
#include <dbus-method-dispatcher.h>
......@@ -60,13 +61,9 @@
#define GCONF_PATH_CONNECTIONS "/system/networking/connections"
#define GCONF_PATH_WIRELESS_NETWORKS "/system/networking/wireless/networks"
#define GCONF_PATH_WIRELESS "/system/networking/wireless"
#define GCONF_PATH_VPN_CONNECTIONS "/system/networking/vpn_connections"
#define GCONF_PATH_PREFS "/apps/NetworkManagerApplet"
typedef struct VPNConnection VPNConnection;
#define NM_TYPE_APPLET (nma_get_type())
#define NM_APPLET(object) (G_TYPE_CHECK_INSTANCE_CAST((object), NM_TYPE_APPLET, NMApplet))
#define NM_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_APPLET, NMAppletClass))
......@@ -93,14 +90,15 @@ typedef struct
GObject parent_instance;
NMClient *nm_client;
NMVPNManager *vpn_manager;
NMAccessPoint *current_ap;
gulong wireless_strength_monitor;
GHashTable *vpn_connections;
NMSettings * settings;
GConfClient * gconf_client;
guint gconf_prefs_notify_id;
guint gconf_vpn_notify_id;
char * glade_file;
/* Data model elements */
......@@ -162,9 +160,6 @@ GType nma_get_type (void);
NMApplet * nm_applet_new (void);
void nma_schedule_warning_dialog (NMApplet *applet, const char *msg);
void nma_show_vpn_failure_alert (NMApplet *applet, const char *member, const char *vpn_name, const char *error_msg);
void nma_show_vpn_login_banner (NMApplet *applet, const char *vpn_name, const char *banner);
const char * nma_escape_ssid (const char * ssid, guint32 len);
static inline gboolean
......
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#include <string.h>
#include <gconf/gconf-client.h>
#include "vpn-connection-info.h"
struct _VPNConnectionInfo {
char *name;
GConfClient *client;
};
#define NM_GCONF_VPN_CONNECTIONS_PATH "/system/networking/vpn_connections"
static VPNConnectionInfo *
vpn_connection_info_new (GConfClient *client, const char *name)
{
VPNConnectionInfo *info;
info = g_slice_new (VPNConnectionInfo);
info->name = g_strdup (name);
info->client = client;
return info;
}
void
vpn_connection_info_destroy (VPNConnectionInfo *info)
{
if (info) {
g_free (info->name);
g_object_unref (info->client);
g_slice_free (VPNConnectionInfo, info);
}
}
GSList *
vpn_connection_info_list (void)
{
GConfClient *client;
GSList *gconf_dirs;
GSList *iter;
int dir_strlen;
GError *err = NULL;
GSList *list = NULL;
client = gconf_client_get_default ();
gconf_dirs = gconf_client_all_dirs (client, NM_GCONF_VPN_CONNECTIONS_PATH, &err);
if (err) {
g_warning ("Could not list VPN connections: %s", err->message);
g_error_free (err);
goto out;
}
dir_strlen = strlen (NM_GCONF_VPN_CONNECTIONS_PATH) + 1;
for (iter = gconf_dirs; iter; iter = iter->next) {
char *path = (char *) iter->data;
list = g_slist_prepend (list, vpn_connection_info_new (client, path + dir_strlen));
g_free (path);
}
g_slist_free (gconf_dirs);
out:
g_object_unref (client);
return list;
}
const char *
vpn_connection_info_get_name (VPNConnectionInfo *info)
{
g_return_val_if_fail (info != NULL, NULL);
return info->name;
}
static char *
get_gconf_key (VPNConnectionInfo *info, const char *key)
{
return g_strconcat (NM_GCONF_VPN_CONNECTIONS_PATH, "/", info->name, "/", key, NULL);
}
char *
vpn_connection_info_get_service (VPNConnectionInfo *info)
{
char *str;
char *key;
GError *err;
g_return_val_if_fail (info != NULL, NULL);
err = NULL;
key = get_gconf_key (info, "service_name");
str = gconf_client_get_string (info->client, key, &err);
g_free (key);
if (err) {
g_warning ("Can not retrieve service name: %s", err->message);
g_error_free (err);
}
return str;
}
static void
property_value_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, data);
}
static void
add_property (GHashTable *properties, const char *key, GConfValue *gconf_value)
{
GValue *value = NULL;
if (!gconf_value)
return;
switch (gconf_value->type) {
case GCONF_VALUE_STRING:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_STRING);
g_value_set_string (value, gconf_value_get_string (gconf_value));
break;
case GCONF_VALUE_INT:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_INT);
g_value_set_int (value, gconf_value_get_int (gconf_value));
break;
case GCONF_VALUE_BOOL:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, gconf_value_get_bool (gconf_value));
break;
default:
break;
}
if (value)
g_hash_table_insert (properties, gconf_unescape_key (key, -1), value);
}
GHashTable *
vpn_connection_info_get_properties (VPNConnectionInfo *info)
{
GHashTable *properties;
GSList *gconf_entries;
GSList *iter;
char *key;
int prefix_len;
GError *err = NULL;
g_return_val_if_fail (info != NULL, NULL);
key = g_strconcat (NM_GCONF_VPN_CONNECTIONS_PATH, "/", info->name, NULL);
prefix_len = strlen (key);
gconf_entries = gconf_client_all_entries (info->client, key, &err);
g_free (key);
if (err) {
g_warning ("Could not list get properties: %s", err->message);
g_error_free (err);
return NULL;
}
properties = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
property_value_destroy);
for (iter = gconf_entries; iter; iter = iter->next) {
GConfEntry *entry = (GConfEntry *) iter->data;
key = (char *) gconf_entry_get_key (entry);
key += prefix_len + 1; /* get rid of the full path */
if (!strcmp (key, "name") ||
!strcmp (key, "service_name") ||
!strcmp (key, "routes") ||
!strcmp (key, "last_attempt_success")) {
gconf_entry_free (entry);
continue;
}
add_property (properties, key, gconf_entry_get_value (entry));
gconf_entry_free (entry);
}
g_slist_free (gconf_entries);
return properties;
}
GSList *
vpn_connection_info_get_routes (VPNConnectionInfo *info)
{
char *key;
GSList *routes;
GError *err;
g_return_val_if_fail (info != NULL, NULL);
err = NULL;
key = g_strconcat (NM_GCONF_VPN_CONNECTIONS_PATH, "/", info->name, "routes", NULL);
routes = gconf_client_get_list (info->client, key, GCONF_VALUE_STRING, &err);
g_free (key);
if (err) {
g_warning ("Can not retrieve routes: %s", err->message);
g_error_free (err);
}
return routes;
}
gboolean
vpn_connection_info_get_last_attempt_success (VPNConnectionInfo *info)
{
char *key;
gboolean success;
GError *err;
g_return_val_if_fail (info != NULL, FALSE);
err = NULL;
key = get_gconf_key (info, "last_attempt_success");
success = gconf_client_get_bool (info->client, key, &err);
g_free (key);
if (err) {
g_warning ("Can not retrieve last_attempt_success: %s", err->message);
g_error_free (err);
}
return success;
}
void
vpn_connection_info_set_last_attempt_success (VPNConnectionInfo *info,
gboolean success)
{
char *key;
GError *err;
g_return_if_fail (info != NULL);
err = NULL;
key = get_gconf_key (info, "last_attempt_success");
success = gconf_client_set_bool (info->client, key, success, &err);
g_free (key);
if (err) {
g_warning ("Can not set last_attempt_success: %s", err->message);
g_error_free (err);
}
}
VPNConnectionInfo *
vpn_connection_info_copy (VPNConnectionInfo *info)
{
g_return_val_if_fail (info != NULL, NULL);
return vpn_connection_info_new (info->client, info->name);
}
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#ifndef NM_VPN_CONNECTION_INFO_H
#define NM_VPN_CONNECTION_INFO_H
#include <glib.h>
typedef struct _VPNConnectionInfo VPNConnectionInfo;
GSList *vpn_connection_info_list (void);
const char *vpn_connection_info_get_name (VPNConnectionInfo *info);
char *vpn_connection_info_get_service (VPNConnectionInfo *info);
GHashTable *vpn_connection_info_get_properties (VPNConnectionInfo *info);
GSList *vpn_connection_info_get_routes (VPNConnectionInfo *info);
gboolean vpn_connection_info_get_last_attempt_success (VPNConnectionInfo *info);
void vpn_connection_info_set_last_attempt_success (VPNConnectionInfo *info,
gboolean success);
VPNConnectionInfo *vpn_connection_info_copy (VPNConnectionInfo *info);
void vpn_connection_info_destroy (VPNConnectionInfo *info);
#endif /* NM_VPN_CONNECTION_INFO_H */
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
......@@ -31,13 +32,12 @@
#include <glib/gi18n.h>
#include <unistd.h>
#include "applet.h"
#include "vpn-password-dialog.h"
#include "nm-utils.h"
typedef struct {
GSList **passwords;
GSList *lines;
int child_stdin;
int num_newlines;
} IOUserData;
......@@ -55,7 +55,6 @@ child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer userd
{
char *str;
IOUserData *io_user_data = (IOUserData *) userdata;
GSList **passwords = (GSList **) io_user_data->passwords;
if (! (condition & G_IO_IN))
goto out;
......@@ -76,7 +75,7 @@ child_stdout_data_cb (GIOChannel *source, GIOCondition condition, gpointer userd
} else if (len > 0) {
/* remove terminating newline */
str[len - 1] = '\0';
*passwords = g_slist_append (*passwords, str);
io_user_data->lines = g_slist_append (io_user_data->lines, str);
}
}
......@@ -84,15 +83,14 @@ out:
return TRUE;
}
GSList *
nma_vpn_request_password (NMApplet *applet, const char *name, const char *service, gboolean retry)
gboolean
nma_vpn_request_password (const char *name, const char *service, gboolean retry, GHashTable *properties)
{
const char *argv[] = {NULL /*"/usr/libexec/nm-vpnc-auth-dialog"*/,
"-n", NULL /*"davidznet42"*/,
"-s", NULL /*"org.freedesktop.vpnc"*/,
"-r",
NULL};
GSList *passwords = NULL;
int child_stdin;
int child_stdout;
GPid child_pid;
......@@ -102,6 +100,7 @@ nma_vpn_request_password (NMApplet *applet, const char *name, const char *servic
GDir *dir;
char *auth_dialog_binary;
IOUserData io_user_data;
gboolean success = FALSE;
auth_dialog_binary = NULL;
......@@ -198,7 +197,7 @@ nma_vpn_request_password (NMApplet *applet, const char *name, const char *servic
/* catch when child is reaped */
g_child_watch_add (child_pid, child_finished_cb, (gpointer) &child_status);
io_user_data.passwords = &passwords;
io_user_data.lines = NULL;
io_user_data.child_stdin = child_stdin;
io_user_data.num_newlines = 0;
......@@ -217,16 +216,31 @@ nma_vpn_request_password (NMApplet *applet, const char *name, const char *servic
g_source_remove (child_stdout_channel_eventid);
g_io_channel_unref (child_stdout_channel);
if (child_status != 0) {
if (passwords != NULL) {
g_slist_foreach (passwords, (GFunc)g_free, NULL);
g_slist_free (passwords);
passwords = NULL;
if (child_status == 0) {
GSList *iter;
for (iter = io_user_data.lines; iter; iter = iter->next) {
GValue *val;
if (!iter->next)
break;
val = g_slice_new0 (GValue);
g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, iter->next->data);
g_hash_table_insert (properties, g_strdup (iter->data), val);
iter = iter->next;
}
}
out:
success = TRUE;
}
g_slist_foreach (io_user_data.lines, (GFunc) g_free, NULL);
g_slist_free (io_user_data.lines);
out:
g_free (auth_dialog_binary);
return passwords;
return success;
}
......@@ -22,11 +22,11 @@
#ifndef VPN_PASSWORD_DIALOG_H
#define VPN_PASSWORD_DIALOG_H
#include "applet.h"
#include <glib.h>
GSList *nma_vpn_request_password (NMApplet *applet,
const char *name,
gboolean nma_vpn_request_password (const char *name,
const char *service,
gboolean retry);
gboolean retry,
GHashTable *properties);
#endif
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/***************************************************************************
* CVSID: $Id: nm-vpn-properties.c 2650 2007-07-26 15:02:54Z dcbw $
*
......@@ -137,8 +138,175 @@ update_edit_del_sensitivity (void)
gtk_widget_set_sensitive (vpn_export, is_editable && is_exportable);
}
static void
property_value_destroy (gpointer data)
{
GValue *value = (GValue *) data;
g_value_unset (value);
g_slice_free (GValue, data);
}
static GHashTable *
create_empty_properties (void)
{
return g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
property_value_destroy);
}
static void
add_property (GHashTable *properties, const char *key, GConfValue *gconf_value)
{
GValue *value = NULL;
if (!gconf_value)
return;
switch (gconf_value->type) {
case GCONF_VALUE_STRING:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_STRING);
g_value_set_string (value, gconf_value_get_string (gconf_value));
break;
case GCONF_VALUE_INT:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_INT);
g_value_set_int (value, gconf_value_get_int (gconf_value));
break;
case GCONF_VALUE_BOOL:
value = g_slice_new0 (GValue);
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, gconf_value_get_bool (gconf_value));
break;
default:
break;
}
if (value)
g_hash_table_insert (properties, gconf_unescape_key (key, -1), value);
}
static GHashTable *
read_properties (const char *path)
{
GHashTable *properties;
GSList *gconf_entries;
GSList *iter;
int prefix_len;
GError *err = NULL;
gconf_entries = gconf_client_all_entries (gconf_client, path, &err);
if (err) {
g_warning ("Could not read properties: %s", err->message);
g_error_free (err);
return NULL;
}
properties = create_empty_properties ();
prefix_len = strlen (path);
for (iter = gconf_entries; iter; iter = iter->next) {
GConfEntry *entry = (GConfEntry *) iter->data;
const char *key;
key = gconf_entry_get_key (entry);
key += prefix_len + 1; /* get rid of the full path */
if (!strcmp (key, "name") ||
!strcmp (key, "service_name") ||
!strcmp (key, "routes") ||
!strcmp (key, "last_attempt_success")) {
gconf_entry_free (entry);
continue;
}
add_property (properties, key, gconf_entry_get_value (entry));
gconf_entry_free (entry);
}
g_slist_free (gconf_entries);
return properties;
}
static void
write_properties (gpointer key, gpointer val, gpointer user_data)
{
GValue *value = (GValue *) val;
char *path = (char *) user_data;
char *esc_key;
char *full_key;
esc_key = gconf_escape_key ((char *) key, -1);
full_key = g_strconcat (path, "/", esc_key, NULL);
g_free (esc_key);
if (G_VALUE_HOLDS_STRING (value))
gconf_client_set_string (gconf_client, full_key, g_value_get_string (value), NULL);
else if (G_VALUE_HOLDS_INT (value))
gconf_client_set_int (gconf_client, full_key, g_value_get_int (value), NULL);
else if (G_VALUE_HOLDS_BOOLEAN (value))
gconf_client_set_bool (gconf_client, full_key, g_value_get_boolean (value), NULL);