Uploaded initial version.
[guivpn] / trunk / vpngui / src / vpngui.c
1 /*
2  * This file is part of vpngui
3  *
4  * Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * */
20
21 #define SCRATCHBOX 0
22
23 #define DBUS_API_SUBJECT_TO_CHANGE
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <net/if.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29
30 #include <dbus/dbus-glib.h>
31 #include <dbus/dbus-glib-bindings.h>
32 #include <dbus/dbus.h>
33
34 #include <glib.h>
35 #include <glib-object.h>
36
37 #include <conicevent.h>
38 #include <coniciap.h>
39 #include <conicconnection.h>
40 #include <conicconnectionevent.h>
41
42 #include <libhildondesktop/libhildondesktop.h>
43 #include <hildon/hildon-dialog.h>
44 #include <hildon/hildon-caption.h>
45 #include <hildon/hildon-check-button.h>
46 #include <hildon/hildon-pannable-area.h>
47 #include <hildon/hildon-banner.h>
48 #include <hildon/hildon-number-editor.h>
49 #include <hildon/hildon-entry.h>
50 #include <sys/types.h>
51 #include <gtk/gtk.h>
52 #include <gconf/gconf.h>
53 #include <gconf/gconf-client.h>
54 #include <stdio.h>
55 #include <string.h>
56
57 /* for temporary stuff like getenv() and sleep() */
58 #include <unistd.h>
59 #include "config.h"
60 #include "vpncfg.h"
61
62 #include <stdlib.h>
63 #include <libosso.h>
64 #include <hildon/hildon-button.h>
65 #include <hildon/hildon-note.h>
66
67 #include "macros.h"
68 #include "vpngui.h"
69
70 #define STATUS_MENU_VPNGUI_ICON      "general_synchronization"
71 #define STATUS_MENU_VPNGUI_ICON_SIZE 48 
72 #define STATUS_AREA_VPNGUI_ICON_SIZE 16 
73
74 #define VPNC_DBUS_LISTENER_TYPE "type='signal',interface='org.maemo.vpnc'"
75 #define VPNC_DBUS_LISTENER_SERVICE "org.maemo.vpnc"
76 #define VPNC_DBUS_LISTENER_SIGNAL "dBusSignal"
77
78 #define DEBUG
79
80 #ifdef DEBUG
81 #  define TRACE(fmtstr, args...) \
82         printf("\033[1;32VPNGUI_PLUGIN\033[0;39m: %s: " fmtstr "\n", \
83                         __func__, ##args); \
84         fflush (stdout)
85 #else
86 #  define TRACE(fmtstr, args...) {}
87 #endif
88 static gchar *iface_addr(const gchar *iface);
89 static gboolean do_disconnect(PluginInfo *self, const gboolean forced);
90 static void vpngui_destroy(GObject *object);
91 void error_msg(const char *format, ...)
92 {
93         g_debug("Executing %s", __PRETTY_FUNCTION__);
94         GtkWidget* dialog;
95         gchar *string;
96         va_list args;
97         va_start(args, format);
98         string = g_strdup_vprintf(format, args);
99         dialog = hildon_note_new_information_with_icon_name(NULL, string,
100                         GTK_STOCK_DIALOG_ERROR);
101         gtk_dialog_run(GTK_DIALOG(dialog));
102         gtk_widget_destroy(GTK_WIDGET(dialog));
103         g_free(string);
104         va_end(args);
105 }
106
107 struct VpnGuiListData{
108         GtkWidget *radio_button;
109         int ap_no;
110         char* vpn_name;
111 };
112 struct VpnGuiListData *vpn_data;
113 static void connection_cb (ConIcConnection *ciconn, ConIcConnectionEvent *event, PluginInfo *self);
114 static gboolean ensure_network(PluginInfo *self);       
115 static void save_config(PrivateVpnDetails *vpn_settings,int);
116 void vpn_access_points_settings_dialog_response (GtkDialog *settings_dialog,
117                 gint response,
118                 PluginInfo   *self);
119
120 static void vpngui_connect_dialog( GtkButton   *button,PluginInfo  *self);
121 static ConIcConnection *ciconn = NULL;
122 static gboolean connecting = FALSE;
123 static gboolean arewe_connected = FALSE; 
124 static gboolean show_settings = TRUE; 
125 static gboolean isvpngui_connected = FALSE;
126 static gboolean show_disconnect_button = FALSE;
127                 
128 /* Paths to configs. Ugly, but works... */
129 char vpn_gconf_vpn_name[]=VPN_GCONF_VPN_NAME;
130 char vpn_gconf_user[]=VPN_GCONF_USER;
131 char vpn_gconf_passwd[]=VPN_GCONF_PASSWD;
132 char vpn_gconf_passwd_obf[]=VPN_GCONF_PASSWD_OBF;
133 char vpn_gconf_gwaddr[]=VPN_GCONF_GWADDR;
134 char vpn_gconf_group[]=VPN_GCONF_GROUP;
135 char vpn_gconf_secret[]=VPN_GCONF_SECRET;
136 char vpn_gconf_secret_obf[]=VPN_GCONF_SECRET_OBF;
137 char vpn_gconf_proxy_mode[]=VPN_GCONF_PROXY_MODE;
138 char vpn_gconf_proxy_server[]=VPN_GCONF_PROXY_SERVER;
139 char vpn_gconf_proxy_port[]=VPN_GCONF_PROXY_PORT;
140 char vpn_gconf_proxy_autoconfig_url[]=VPN_GCONF_PROXY_AUTOCONFIG_URL;
141 char vpn_gconf_proxy_ignore_hosts[]=VPN_GCONF_PROXY_IGNORE_HOSTS;
142     
143 char vpn_gconf_rekey_interval[]=VPN_GCONF_REKEY_INTERVAL;
144 char vpn_gconf_nat_keepalive[]=VPN_GCONF_NAT_KEEPALIVE;
145 /* Change the gconf paths for our settings according to vpn_ap (0...X) */
146 void vpn_make_config_paths(int ap_no)
147 {
148         g_debug("Executing %s", __PRETTY_FUNCTION__);
149         char vpn_ap[1];
150         sprintf (vpn_ap,"%d",ap_no); 
151
152         sprintf(vpn_gconf_vpn_name,VPN_GCONF_VPN_NAME,vpn_ap);
153         sprintf(vpn_gconf_user,VPN_GCONF_USER,vpn_ap);
154         sprintf(vpn_gconf_passwd,VPN_GCONF_PASSWD,vpn_ap);
155         sprintf(vpn_gconf_passwd_obf,VPN_GCONF_PASSWD_OBF,vpn_ap);
156         sprintf(vpn_gconf_gwaddr,VPN_GCONF_GWADDR,vpn_ap);
157         sprintf(vpn_gconf_group,VPN_GCONF_GROUP,vpn_ap);
158         sprintf(vpn_gconf_secret,VPN_GCONF_SECRET,vpn_ap);
159         sprintf(vpn_gconf_secret_obf,VPN_GCONF_SECRET_OBF,vpn_ap);
160         sprintf(vpn_gconf_proxy_mode,VPN_GCONF_PROXY_MODE,vpn_ap);
161         sprintf(vpn_gconf_proxy_server,VPN_GCONF_PROXY_SERVER,vpn_ap);
162         sprintf(vpn_gconf_proxy_port,VPN_GCONF_PROXY_PORT,vpn_ap);
163         sprintf(vpn_gconf_rekey_interval,VPN_GCONF_REKEY_INTERVAL,vpn_ap);
164         sprintf(vpn_gconf_nat_keepalive,VPN_GCONF_NAT_KEEPALIVE,vpn_ap);
165         sprintf(vpn_gconf_proxy_autoconfig_url,VPN_GCONF_PROXY_AUTOCONFIG_URL,vpn_ap);
166         sprintf(vpn_gconf_proxy_ignore_hosts,VPN_GCONF_PROXY_IGNORE_HOSTS,vpn_ap);
167 }
168
169 gboolean get_vpn_name_config(GList* list)//int ap_no,char **vpn_name)
170 {
171         GConfClient *gconf = NULL;
172         char vpn_ap_no[1];
173         gconf = gconf_client_get_default();
174         int i;
175         for(i=0;i<g_list_length(list);i++)
176         {
177                 vpn_data = ((struct VpnGuiListData*)g_list_nth_data(list,i));
178                 vpn_data->vpn_name = NULL;
179                 sprintf (vpn_ap_no,"%d",vpn_data->ap_no);
180                 sprintf(vpn_gconf_vpn_name,VPN_GCONF_VPN_NAME,vpn_ap_no);
181                 vpn_data->vpn_name = gconf_client_get_string(gconf, vpn_gconf_vpn_name, NULL);
182                 if(vpn_data->vpn_name == NULL)
183                 {
184                         //g_free(vpn_data);
185                         list = g_list_remove(list,vpn_data);
186                 }
187         }
188         g_object_unref(gconf);
189         return TRUE;
190 }
191
192 /* Get the connection settings from saved configuration files */
193 static void get_config(PrivateVpnDetails *vpn_settings,int ap_no)
194 {
195         GConfClient *gconf = NULL;
196         g_debug("Executing %s", __PRETTY_FUNCTION__);
197         g_return_if_fail(vpn_settings);
198         /* Fetch the correct AP paths based on vpn_ap variable */
199
200         vpn_make_config_paths(ap_no);
201         gconf = gconf_client_get_default();
202         vpn_settings->gwaddress = gconf_client_get_string(gconf, vpn_gconf_gwaddr, NULL);
203         vpn_settings->group = gconf_client_get_string(gconf, vpn_gconf_group, NULL);
204         vpn_settings->secret = gconf_client_get_string(gconf, vpn_gconf_secret, NULL);
205         vpn_settings->secret_obf = gconf_client_get_bool(gconf, vpn_gconf_secret_obf, NULL);
206         vpn_settings->username = gconf_client_get_string(gconf, vpn_gconf_user, NULL);
207         vpn_settings->vpn_name = gconf_client_get_string(gconf, vpn_gconf_vpn_name, NULL);
208         vpn_settings->password = "";
209         vpn_settings->password_obf = FALSE;
210         /* Should be asked from GUI */
211
212         vpn_settings->rekeyinterval = VPN_REKEY_INTERVAL;
213         vpn_settings->natkeepalive = VPN_NAT_KEEPALIVE;
214         vpn_settings->proxytype = gconf_client_get_string(gconf, vpn_gconf_proxy_mode, NULL);
215         vpn_settings->proxy_server = gconf_client_get_string(gconf, vpn_gconf_proxy_server, NULL);
216         vpn_settings->proxy_port = gconf_client_get_int(gconf, vpn_gconf_proxy_port, NULL);
217         vpn_settings->proxy_autoconfig_url = gconf_client_get_string(gconf, vpn_gconf_proxy_autoconfig_url, NULL);
218         vpn_settings->proxy_ignore_hosts = gconf_client_get_list(gconf, vpn_gconf_proxy_ignore_hosts,GCONF_VALUE_STRING, NULL);
219         
220         g_object_unref(gconf);
221 }
222
223 static void plugin_callback (GtkWidget *Radio_button,
224                                PluginInfoPrivate  *priv)
225 {
226         
227         g_debug("Executing %s", __PRETTY_FUNCTION__);  
228         if(show_disconnect_button)
229         {
230                 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(((struct VpnGuiListData*)g_list_nth_data(priv->list, priv->connected_vpn_ap_ui))->radio_button)))
231                 {
232                         gtk_button_set_label (GTK_BUTTON(priv->connect_button),"Disconnect");
233                         gtk_widget_set_sensitive(priv->connect_button,TRUE);
234                         /* If vpn is activated for a particular access point, then 
235                          * Delete button for that access point needs to be disabled.
236                          * */
237                         gtk_widget_set_sensitive(priv->delete_button,FALSE);
238                 }
239                 else
240                 {
241                         gtk_button_set_label (GTK_BUTTON(priv->connect_button),"Connect");
242                         gtk_widget_set_sensitive(priv->connect_button,FALSE);
243                         gtk_widget_set_sensitive(priv->delete_button,TRUE);
244                 }
245         }
246         else
247         {
248                         gtk_button_set_label (GTK_BUTTON(priv->connect_button),"Connect");
249                         gtk_widget_set_sensitive(priv->connect_button,TRUE);
250                         gtk_widget_set_sensitive(priv->delete_button,TRUE);
251         }
252         
253 }
254
255 /******************************************************************************
256  * Forward declarations of callback functions.
257  */
258 static void
259 on_main_button_clicked (
260                 GtkButton   *button,
261                 PluginInfo  *self);
262
263 /******************************************************************************
264  * The implementation of the plugin.
265  */
266
267 HD_DEFINE_PLUGIN_MODULE (PluginInfo, vpngui_plugin, HD_TYPE_STATUS_MENU_ITEM);
268
269 static void
270 vpngui_plugin_class_finalize (PluginInfoClass *klass)
271 {
272         TRACE ("");
273 }
274
275 static void
276 vpngui_plugin_class_init (PluginInfoClass *klass)
277 {
278         g_debug("Executing %s", __PRETTY_FUNCTION__);
279         GObjectClass* object_class = G_OBJECT_CLASS (klass);    
280         object_class->finalize = vpngui_destroy;
281         g_type_class_add_private (klass, sizeof (PluginInfoPrivate));
282         TRACE ("");
283         g_debug("Exiting %s", __PRETTY_FUNCTION__);
284 }
285
286 static void vpngui_destroy(GObject *object)
287 {
288         g_debug("Executing %s", __PRETTY_FUNCTION__);
289         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (object);
290         
291         if(priv->vpn_notify)
292         {
293                 g_object_unref(priv->vpn_notify);
294                 priv->vpn_notify = NULL;
295         }
296         if(ciconn)
297         {
298                 g_object_unref(ciconn);
299                 ciconn = NULL;
300         }
301 //      G_OBJECT_CLASS(vpngui_plugin_parent_class)->finalize (object);
302
303         g_debug("Exiting %s", __PRETTY_FUNCTION__);
304 }
305
306 static DBusHandlerResult
307 dbus_signal_filter(
308                 DBusConnection *connection,
309                 DBusMessage *message,
310                 void *user_data)
311 {
312         PluginInfo   *self = (PluginInfo   *)user_data;
313         if (dbus_message_is_signal (message, VPNC_DBUS_LISTENER_SERVICE, VPNC_DBUS_LISTENER_SIGNAL)) {
314         g_debug("Signal has been received in  %s", __PRETTY_FUNCTION__);
315                  DBusError error;
316                  char *s = 0;
317                  dbus_error_init (&error);
318                  if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &s,DBUS_TYPE_INVALID)){
319                         if (g_str_equal("connected", s)) {
320                                 g_debug("connected state called");
321                                 set_state(self, VPN_CONNECTED);
322                         } else if (g_str_equal("disconnected", s)) {
323                                 set_state(self, VPN_DISCONNECTED);
324                                 g_debug ("We have a end DBus message.");
325                         } else {
326                                 g_debug("XXXX unknown state %s\n", s);
327                         }
328                  } else {
329                          dbus_error_free (&error);
330                  }
331                  return DBUS_HANDLER_RESULT_HANDLED;
332          }
333         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
334
335 }
336
337 gboolean register_dbus_signal_filter(
338                 osso_context_t *context,
339                 gpointer user_data)
340 {
341         
342         DBusConnection *bus = (DBusConnection*) osso_get_dbus_connection (context);
343         if (!bus) {
344                 return FALSE;
345         }
346         dbus_bus_add_match (bus, VPNC_DBUS_LISTENER_TYPE, NULL);
347         if (!dbus_connection_add_filter (bus, dbus_signal_filter, user_data, NULL)) {
348                 return FALSE;
349         }
350         return TRUE;
351 }
352
353 static void
354 vpngui_plugin_init (PluginInfo *menu_item)
355 {
356         g_debug("Executing %s", __PRETTY_FUNCTION__);
357         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (menu_item);
358
359         TRACE ("");
360         
361         /**********************************************************************
362          * Initializing osso 
363          */
364         priv->osso_context = osso_initialize(PACKAGE, VERSION, FALSE, NULL);
365         if (!priv->osso_context) {
366                 TRACE ("Error initializing osso");
367         }
368         
369         /**********************************************************************
370          * Setting up a DBus listener, System call
371          */
372          if (!register_dbus_signal_filter (priv->osso_context, menu_item)) {
373                  g_debug ("Unable to register DBUS filter function");
374                  exit (1);
375          }
376         /**********************************************************************
377          * Setting up the locale.
378          */
379         bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
380         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
381         textdomain(GETTEXT_PACKAGE);
382         /**********************************************************************
383          * Creating widgets.
384          */
385
386         priv->icon = gtk_image_new_from_pixbuf(NULL);
387         priv->button = gtk_toggle_button_new();
388         priv->state = VPN_DISCONNECTED;
389         priv->show_connect_dialog = FALSE;
390         priv->vpnc_pid = 0;
391         priv->vpnc_watch_id = 0;
392         priv->old_ip = NULL;
393         priv->list = NULL;
394         priv->total_items = 0;
395         priv->connected_vpn_ap_gconf = VPN_DEFAULT_HIRO_VPN;
396         
397         priv->pixbuf[PIXBUF_ACTIVE] = gdk_pixbuf_new_from_file(ICON_ACTIVE, NULL);
398         priv->pixbuf[PIXBUF_INACTIVE] = gdk_pixbuf_new_from_file(ICON_INACTIVE,NULL);
399         priv->pixbuf[PIXBUF_SUSPENDED] = gdk_pixbuf_new_from_file(ICON_SUSPENDED,NULL);
400         priv->pixbuf[PIXBUF_ACTIVE_SMALL] = gdk_pixbuf_new_from_file(ICON_ACTIVE_SMALL, NULL);
401         priv->pixbuf[PIXBUF_SUSPENDED_SMALL] = gdk_pixbuf_new_from_file(ICON_SUSPENDED_SMALL, NULL);
402         gtk_image_set_from_pixbuf(GTK_IMAGE(priv->icon),
403                         priv->pixbuf[PIXBUF_INACTIVE]);
404         priv->show_icon = FALSE;
405         
406         priv->container_hbox = gtk_hbox_new(FALSE, 0);
407         priv->vbox1 = gtk_vbox_new(FALSE, 0);
408         priv->vbox2 = gtk_vbox_new(FALSE, 0);
409          
410         /*
411          * A button used as a menu item.
412          */
413         priv->button = hildon_button_new (
414                         HILDON_SIZE_FINGER_HEIGHT, 
415                         HILDON_BUTTON_ARRANGEMENT_VERTICAL);
416         gtk_container_set_border_width(GTK_CONTAINER(priv->button), 3);
417          
418         priv->sync_name_label = gtk_label_new("VPN");
419         gtk_misc_set_alignment(GTK_MISC(priv->sync_name_label), .0, .5);
420         
421         priv->prof_name_label = gtk_label_new(" ");
422         gtk_misc_set_alignment(GTK_MISC(priv->prof_name_label), .0, .5);
423          
424         gtk_widget_set_size_request(priv->icon,
425                         STATUS_MENU_VPNGUI_ICON_SIZE,
426                         STATUS_MENU_VPNGUI_ICON_SIZE);
427
428         gtk_container_add(GTK_CONTAINER(priv->button), priv->container_hbox);
429         gtk_box_pack_start(GTK_BOX(priv->container_hbox),  priv->icon,
430                         FALSE, TRUE, 0);
431         gtk_box_pack_start(GTK_BOX(priv->container_hbox), priv->vbox1, TRUE, TRUE, 0);
432         gtk_box_pack_start(GTK_BOX(priv->vbox1), priv->vbox2, TRUE, FALSE, 0);
433         gtk_box_pack_start(GTK_BOX(priv->vbox2), priv->sync_name_label, FALSE, FALSE, 0);
434         gtk_box_pack_start(GTK_BOX(priv->vbox2), priv->prof_name_label, FALSE, FALSE, 0);
435
436         priv->button2 = gtk_button_new();
437         gtk_button_set_label (GTK_BUTTON(priv->button2),"Connect");
438         
439         gtk_container_add(GTK_CONTAINER(menu_item), priv->button);
440         gtk_widget_show_all (GTK_WIDGET(priv->button));
441         gtk_widget_show (GTK_WIDGET(menu_item));
442                 
443         /**********************************************************************
444          * Connecting signals.
445          */
446         g_signal_connect (priv->button, "clicked",
447                         G_CALLBACK (on_main_button_clicked), menu_item);
448             
449          /* Initialize configuration from gconf */
450         get_config(&priv->vpn_settings,priv->connected_vpn_ap_gconf); 
451         priv->vpnc_config = NULL;
452         priv->vpn_notify = NULL;
453            /* Make a new connection */
454         ciconn = con_ic_connection_new ();
455         if (!ciconn) {
456                 error_msg("Con_ic_connection_new() failed");
457         }
458         else
459         {
460                 /* Setup event callbacks: route events -> connection_cb() */
461                 /* Pass the userdata along */
462                 g_signal_connect (ciconn, "connection-event", G_CALLBACK(connection_cb), menu_item);
463                 /* err.. what? */
464                 g_object_set (ciconn, "automatic-connection-events", TRUE, NULL);
465         }
466                 
467         /* While upgrading the component this cannot register to exisiting type.
468          * One way to avoid is to use dsme tool to shutdown hildon-status-menu
469          * or reboot
470          * */
471         priv->vpn_notify = g_object_new(VPN_TYPE_NOTIFY, NULL);
472         g_debug("Exiting %s", __PRETTY_FUNCTION__);
473         
474 }
475
476 /* Reconnect the VPN */
477 static gboolean do_reconnect(PluginInfo *self)
478 {
479         g_debug("Executing %s", __PRETTY_FUNCTION__);
480         return vpnc_restart(self);
481 }
482
483 /* Connection event magic */
484 static void
485 connection_cb (ConIcConnection *ciconn, ConIcConnectionEvent *event, PluginInfo *self)
486 {
487         g_debug("Executing %s (%p, )", __PRETTY_FUNCTION__, event);
488         const gchar *iap_id, *bearer;
489         ConIcConnectionStatus status;
490         ConIcConnectionError error;
491         /* check the events */
492         /* g_assert(CON_IC_IS_CONNECTION_EVENT(event)); */
493         /* get the userdata */
494         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
495         /* get the event info */
496         status = con_ic_connection_event_get_status(event);
497         error = con_ic_connection_event_get_error(event);
498         iap_id = con_ic_event_get_iap_id(CON_IC_EVENT(event));
499         bearer = con_ic_event_get_bearer_type(CON_IC_EVENT(event));
500         
501         /* Error handling. Break out if there is a error...*/
502         switch (error) {
503                 case CON_IC_CONNECTION_ERROR_NONE:
504                         /* no error is good error :) */
505                         break;
506                 case CON_IC_CONNECTION_ERROR_INVALID_IAP:
507                         error_msg ("CON_IC: INVALID_IAP (%s, %s, %i, %i)", iap_id, bearer, status, error);
508                         arewe_connected = FALSE;
509                         priv->have_network = FALSE;
510                         connecting = FALSE;
511                         break;
512                 case CON_IC_CONNECTION_ERROR_CONNECTION_FAILED:
513                         error_msg ("CON_IC: Connection failed (%s, %s, %i, %i)", iap_id, bearer, status, error);
514                         arewe_connected = FALSE;
515                         priv->have_network = FALSE;
516                         connecting = FALSE;
517                         break;
518                 case CON_IC_CONNECTION_ERROR_USER_CANCELED:
519                         error_msg ("CON_IC: User cancelled (%s, %s, %i, %i)", iap_id, bearer, status, error);
520                         arewe_connected = FALSE;
521                         priv->have_network = FALSE;
522                         connecting = FALSE;
523                         break;
524                 default:
525                         error_msg ("CON_IC: Unexpected error (%s, %s, %i, %i)", iap_id, bearer, status, error);
526                         arewe_connected = FALSE;
527                         priv->have_network = FALSE;
528                         connecting = FALSE;
529                         break;
530         }
531         
532         /* Status events */
533         /* Unblock only if connected... (or error) */
534         switch (status) {
535                 case CON_IC_STATUS_CONNECTED:
536                         g_debug("%s: CONNECTED (%s, %s, %i, %i)", __PRETTY_FUNCTION__, iap_id, bearer, status, error);
537                         arewe_connected = TRUE;
538                         priv->have_network = TRUE;
539                         connecting = FALSE;
540                         break;
541                 case CON_IC_STATUS_DISCONNECTED:
542                         /* error_msg ("DISCONNECTED (%s, %s, %i, %i)", iap_id, bearer, status, error); */
543                         g_debug("%s: DISCONNECTED (%s, %s, %i, %i)", __PRETTY_FUNCTION__, iap_id, bearer, status, error);
544                         arewe_connected = FALSE;                        
545                         priv->have_network = FALSE;
546                         /* connecting = FALSE; */
547                         if (priv->state == VPN_CONNECTED)
548                         {
549                                 gtk_image_set_from_pixbuf(GTK_IMAGE(priv->icon),priv->pixbuf[PIXBUF_SUSPENDED]);
550                                 hd_status_plugin_item_set_status_area_icon (
551                                         HD_STATUS_PLUGIN_ITEM (self),
552                                         priv->pixbuf[PIXBUF_SUSPENDED_SMALL]);
553                                 priv->show_icon = FALSE;
554                                 isvpngui_connected = FALSE;                             
555                                 show_disconnect_button = TRUE; // To Display Connect in the button                      
556                                 /* Fix me : Hack : this is done if the network has moved from wireless to 3G */         
557                                 gchar *wlan_addr =NULL;
558                                 wlan_addr   = iface_addr("wlan0");
559                                 if(wlan_addr == NULL)   /* if the connection is Point to Point Protocol */
560                                         wlan_addr   = iface_addr("ppp0");
561                                 if(wlan_addr == NULL)   /* if the connection is 3G network */
562                                         wlan_addr   = iface_addr("gprs0");
563                                 /*  if ip has changed, we are disconnecting */
564                                 if(wlan_addr != NULL)
565                                 {
566                                         if (priv->old_ip != NULL)
567                                         {
568                                                 if (strcmp(priv->old_ip, wlan_addr))
569                                                 {
570                                                         if(wlan_addr!= NULL)
571                                                         {
572                                                                 g_free(wlan_addr);
573                                                                 wlan_addr = NULL;
574                                                         }
575                                                         do_disconnect(self, FALSE);
576                                                 }
577                                         }
578                                         if(wlan_addr!= NULL)
579                                         {
580                                                 g_free(wlan_addr);
581                                                 wlan_addr = NULL;
582                                         }
583                                 }
584                         }
585                         break;
586                 case CON_IC_STATUS_DISCONNECTING:
587                                 g_debug("%s: DISCONNECTING (%s, %s, %i, %i)", __PRETTY_FUNCTION__, iap_id, bearer, status, error);
588                                 break;
589
590                 default:
591                                 g_debug("%s: CON_IC: UNKNOWN STATUS (%s, %s, %i, %i)", __PRETTY_FUNCTION__, iap_id, bearer, status, error);
592                                 break;
593         }
594         
595         
596         if(priv->have_network) {
597                 if (priv->show_connect_dialog) {
598                         g_debug("%s: Showing connecton dialog...", __PRETTY_FUNCTION__);
599                         priv->show_connect_dialog = FALSE;
600                         vpngui_connect_dialog(GTK_BUTTON(priv->button2), self);
601                 } else {
602                         if(!isvpngui_connected)
603                         {
604                                 g_debug("%s: Reconnecting...", __PRETTY_FUNCTION__);
605                                 
606                                 do_reconnect(self);
607                         }
608                         
609                 }
610         }
611 }
612
613 /* Try to make sure we have network connection before launching vpnc. Using the new liconic */
614 static gboolean ensure_network(PluginInfo *self)
615 {
616         g_debug("Executing %s", __PRETTY_FUNCTION__);
617         /* get the userdata */
618         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
619
620         if (!ciconn) {
621                 error_msg("Con_ic_connection_new() failed");
622                 return FALSE;
623         }
624         
625         if(priv->have_network) return TRUE;
626         connecting = TRUE;
627         /* Request for connection ... */
628         if (!con_ic_connection_connect (ciconn, CON_IC_CONNECT_FLAG_NONE)) {
629                 error_msg ("Con_ic_connection_connect() failed.");
630         }
631         
632         /* Loop here in event loop until connecting goes FALSE */
633         while (connecting) {
634                 /* Iterate the main loop so that the signal can be called. */
635                 if (g_main_context_pending (NULL)) {
636                         g_main_context_iteration (NULL, FALSE);
637                 }
638         }
639
640         /* Return TRUE/FALSE, depending how the events when :) */
641         g_debug("Exiting %s with res = %d", __PRETTY_FUNCTION__, arewe_connected);
642         return arewe_connected;
643 }
644 void save_vpn_configuration(PluginInfo *self,int ap_no)
645 {    
646         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
647         gchar               *message = NULL;
648         char *markup;
649         /* Fetch the correct info from gconf */
650         get_config(&priv->vpn_settings,ap_no);
651         /* Display the name of the Access point */
652         message = g_strdup(priv->vpn_settings.vpn_name);
653         markup = g_markup_printf_escaped ("<span color=\"#95EAEA\"><small>%s</small></span>", message);
654         gtk_label_set_markup (GTK_LABEL (priv->prof_name_label), markup);
655         g_free (markup);
656         g_free (message);
657         /* Is this really needed... */
658         priv->vpnc_config = "";
659         
660 }
661
662 static int sort_data(gconstpointer a, gconstpointer b)
663 {
664      struct VpnGuiListData* first = (struct VpnGuiListData*)a;
665      struct VpnGuiListData* second = (struct VpnGuiListData*)b;
666      gint ret = g_ascii_strcasecmp((char*)(first->vpn_name),(char*)(second->vpn_name));
667      return ret;
668 }                                       
669
670 GList*  get_vpn_config_list()
671 {
672         GConfClient *gconf = NULL;
673         GSList *list =NULL;
674         GList *priv_list = NULL;
675         gconf = gconf_client_get_default();
676         list = gconf_client_all_dirs(gconf,VPN_GCONF_PATH,NULL);
677         
678         int i;
679         for(i=0;i<g_slist_length(list);i++)
680         {
681                 vpn_data= (struct VpnGuiListData*)malloc(sizeof(struct VpnGuiListData*));
682                 int num ;
683                 char *name = (char*)g_slist_nth_data(list,i);
684                 sscanf(name,VPN_GCONF_AP_PATH_NO,&num);
685                 sprintf(vpn_gconf_vpn_name,VPN_GCONF_VPN_NAME_NO,num);
686                 vpn_data->vpn_name = gconf_client_get_string(gconf, vpn_gconf_vpn_name, NULL);
687                 if(vpn_data->vpn_name == NULL)
688                 {
689                         if(vpn_data)
690                         {
691                                 free(vpn_data);
692                                 vpn_data = NULL;
693                         }
694                         g_free(g_slist_nth_data(list,i));
695                         continue;
696                 }
697                 
698                 vpn_data->ap_no = num;
699                 priv_list = g_list_append(priv_list,vpn_data);
700                 g_free(g_slist_nth_data(list,i));
701         }
702         g_slist_free(list);
703         g_object_unref(gconf);
704         if(g_list_length(priv_list) >1)
705                 priv_list = g_list_sort(priv_list,sort_data);
706          
707         return priv_list;
708 }
709
710 void vpn_settings_screen(PluginInfoPrivate   *priv,int ap_no,gboolean show_new_vpn_ap)
711 {
712         GtkWidget *dialog ;
713         GtkWidget *container_hbox, *vbox , *scrolledwindow;
714         GtkWidget *name_entry,*gw_entry, *group_entry, *secret_entry;
715         GtkWidget *proxy_server_entry, *proxy_port_entry;
716
717         gboolean show_settings_again = FALSE;   
718
719         GtkWidget *obf_check_entry;
720         PrivateVpnDetails vpn_settings;
721         g_debug("Executing %s", __PRETTY_FUNCTION__);
722           
723         get_config(&vpn_settings,ap_no);        
724         dialog = gtk_dialog_new_with_buttons("Access point settings",
725                                 NULL,
726                                 GTK_DIALOG_MODAL ,
727                                 GTK_STOCK_OK,
728                                 GTK_RESPONSE_OK,
729                                 GTK_STOCK_CANCEL,
730                                 GTK_RESPONSE_CANCEL,
731                                 NULL);
732
733
734         container_hbox = gtk_hbox_new(FALSE, 0);
735         gtk_widget_set_size_request(container_hbox,300,400);
736         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), container_hbox);
737         scrolledwindow = hildon_pannable_area_new();
738         gtk_box_pack_start (GTK_BOX (container_hbox),scrolledwindow, TRUE, TRUE, 0);
739
740         vbox = gtk_vbox_new(FALSE, 0);
741         hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(scrolledwindow),vbox);              
742 //      gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 6);
743         GtkSizeGroup *group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
744         
745         name_entry =  hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
746         hildon_gtk_entry_set_input_mode(GTK_ENTRY(name_entry),HILDON_GTK_INPUT_MODE_FULL);
747         gw_entry =  hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
748         hildon_gtk_entry_set_input_mode(GTK_ENTRY(gw_entry),HILDON_GTK_INPUT_MODE_FULL);
749         group_entry =  hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
750         hildon_gtk_entry_set_input_mode(GTK_ENTRY(group_entry), HILDON_GTK_INPUT_MODE_FULL);
751         secret_entry =  hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
752         hildon_gtk_entry_set_input_mode(GTK_ENTRY(secret_entry),HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
753         obf_check_entry = hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT);
754         gtk_button_set_label (GTK_BUTTON (obf_check_entry), "IPSec Secret obfuscated");
755         proxy_server_entry =  hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
756         hildon_gtk_entry_set_input_mode(GTK_ENTRY(proxy_server_entry),HILDON_GTK_INPUT_MODE_FULL);
757         proxy_port_entry = hildon_number_editor_new(0, 65535);
758         int proxy_port = 8080;
759         
760         GtkWidget *name_caption = hildon_caption_new(group,
761                         "Name",
762                         name_entry,
763                         NULL,
764                         HILDON_CAPTION_OPTIONAL);
765         GtkWidget *gw_caption = hildon_caption_new(group,
766                         "Gateway address",
767                         gw_entry,
768                         NULL,
769                         HILDON_CAPTION_OPTIONAL);
770         GtkWidget *group_caption = hildon_caption_new(group,
771                         "IPSec Group",
772                         group_entry,
773                         NULL,
774                         HILDON_CAPTION_OPTIONAL);
775         GtkWidget *secret_caption = hildon_caption_new(group,
776                         "IPSec Secret",
777                         secret_entry,
778                         NULL,
779                         HILDON_CAPTION_OPTIONAL);
780         GtkWidget *proxy_server_caption = hildon_caption_new(group,
781                         "VPN HTTP(S) proxy host",
782                         proxy_server_entry,
783                         NULL,
784                         HILDON_CAPTION_OPTIONAL);
785         GtkWidget *proxy_port_caption = hildon_caption_new(group,
786                         "VPN HTTP(S) proxy port",
787                         proxy_port_entry,
788                         NULL,
789                         HILDON_CAPTION_OPTIONAL);
790
791         gtk_box_pack_start (GTK_BOX(vbox),name_caption, TRUE, TRUE, 0);
792         gtk_box_pack_start (GTK_BOX(vbox),gw_caption, TRUE, TRUE, 0);
793         gtk_box_pack_start (GTK_BOX(vbox),group_caption, TRUE, TRUE, 0);
794         gtk_box_pack_start (GTK_BOX(vbox),secret_caption, TRUE, TRUE, 0);
795         gtk_box_pack_start (GTK_BOX(vbox),obf_check_entry, TRUE, TRUE, 0);
796         gtk_box_pack_start (GTK_BOX(vbox),proxy_server_caption, TRUE, TRUE, 0);
797         gtk_box_pack_start (GTK_BOX(vbox),proxy_port_caption, TRUE, TRUE, 0);
798
799         if (vpn_settings.vpn_name) {
800                 gtk_entry_set_text(GTK_ENTRY(name_entry), vpn_settings.vpn_name);
801         }
802         if (vpn_settings.gwaddress) {
803                 gtk_entry_set_text(GTK_ENTRY(gw_entry), vpn_settings.gwaddress);
804         }
805         if (vpn_settings.group) {
806                 gtk_entry_set_text(GTK_ENTRY(group_entry), vpn_settings.group);
807         }
808         if (vpn_settings.secret) {
809                 gtk_entry_set_text(GTK_ENTRY(secret_entry), vpn_settings.secret);
810         }
811         hildon_check_button_set_active(HILDON_CHECK_BUTTON(obf_check_entry),vpn_settings.secret_obf);
812
813         if (vpn_settings.proxy_server) {
814                 gtk_entry_set_text(GTK_ENTRY(proxy_server_entry), vpn_settings.proxy_server);
815         }
816         if (vpn_settings.proxy_port) {
817                 proxy_port = vpn_settings.proxy_port;
818         }
819         hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(proxy_port_entry),  proxy_port);
820         
821
822         gtk_widget_show_all(GTK_WIDGET(dialog));
823         if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
824                 if(!strcmp(gtk_entry_get_text(GTK_ENTRY(name_entry)),""))
825                 {
826                         GtkWidget *error_dialog = gtk_dialog_new_with_buttons("Error Message",
827                                         NULL,
828                                         GTK_DIALOG_MODAL ,
829                                         GTK_STOCK_OK,
830                                         GTK_RESPONSE_OK,
831                                         GTK_STOCK_CANCEL,
832                                         GTK_RESPONSE_CANCEL,
833                                         NULL);
834                         GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
835                         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(error_dialog)->vbox), hbox);
836                         GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
837                         gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 6);
838                         GtkWidget *label = gtk_label_new("Data is not saved as Name Entry was not given");
839                         gtk_container_add(GTK_CONTAINER(GTK_BOX(vbox)), label);
840                         gtk_widget_show_all(GTK_WIDGET(error_dialog));
841                         gtk_dialog_run(GTK_DIALOG(error_dialog)); 
842                         gtk_widget_destroy(GTK_WIDGET(error_dialog));
843                         
844                         show_settings_again = TRUE;                     
845                 }
846                 if(!show_settings_again)
847                 {
848                         vpn_settings.vpn_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(name_entry)));
849                         vpn_settings.gwaddress = g_strdup(gtk_entry_get_text(GTK_ENTRY(gw_entry)));
850                         vpn_settings.group = g_strdup(gtk_entry_get_text(GTK_ENTRY(group_entry)));
851                         vpn_settings.secret = g_strdup(gtk_entry_get_text(GTK_ENTRY(secret_entry)));
852                         vpn_settings.secret_obf = hildon_check_button_get_active(HILDON_CHECK_BUTTON(obf_check_entry));
853                         vpn_settings.proxy_server = g_strdup(gtk_entry_get_text(GTK_ENTRY(proxy_server_entry)));
854                         vpn_settings.proxy_port = hildon_number_editor_get_value(HILDON_NUMBER_EDITOR(proxy_port_entry));
855                         if (g_str_equal(vpn_settings.proxy_server, "")) {
856                                 vpn_settings.proxytype = "none";
857                         } else {
858                                 vpn_settings.proxytype = "manual";
859                         }
860                         if ( show_new_vpn_ap ){
861                                 priv->total_items++;
862                         }
863                         
864                         save_config(&vpn_settings,ap_no);
865                         /* Enable the Connect Button, Delete Button,Settings Button */
866                         gtk_widget_set_sensitive(priv->connect_button,TRUE);
867                         gtk_widget_set_sensitive(priv->delete_button,TRUE);
868                         gtk_widget_set_sensitive(priv->settings_button,TRUE);
869                 }
870         }
871         gtk_widget_destroy(GTK_WIDGET(dialog));
872         if(show_settings_again)
873                 vpn_settings_screen(priv,ap_no,show_new_vpn_ap);
874 }
875
876 void delete_vpn_ap_settings(int ap_no)
877 {
878         GConfClient *gconf = NULL;
879         gconf = gconf_client_get_default();
880         char dir[22];
881         sprintf(dir,VPN_GCONF_AP_PATH_NO,ap_no);
882         gconf_client_recursive_unset(gconf,dir,0,NULL);
883         g_object_unref(gconf);
884 }
885
886 void vpn_access_points_settings_dialog_response (GtkDialog *settings_dialog,
887                 gint response,
888                 PluginInfo   *self)
889 {
890         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
891         gboolean show_new_vpn_ap =FALSE;
892         int ap_no_gui=0; /* Selected VPN access point.. From GUI */
893         int ap_no_gconf=0; /* VPN access point .. From GConf */
894         for(ap_no_gui=0;ap_no_gui<priv->total_items;ap_no_gui++)
895         {
896                 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(((struct VpnGuiListData*)g_list_nth_data(priv->list,ap_no_gui))->radio_button)))
897                 {
898                 ap_no_gconf = ((struct VpnGuiListData*)g_list_nth_data(priv->list,ap_no_gui))->ap_no;                   
899                         break;
900                 }
901         }
902         int delete_data;
903         for(delete_data=0;delete_data<g_list_length(priv->list);delete_data++)
904         {
905                 gtk_widget_destroy(GTK_WIDGET(((struct VpnGuiListData*)g_list_nth_data(priv->list,delete_data))->radio_button));
906                 g_free((struct VpnGuiListData*)g_list_nth_data(priv->list,delete_data));
907         }
908         g_list_free(priv->list);        
909         priv->list = NULL;
910         gtk_widget_destroy(GTK_WIDGET(settings_dialog));
911         switch (response)
912         {
913         case VPN_ACCESS_POINT_NEW:
914                 /* random_no creation */
915                 srand((unsigned)time(0));
916                 ap_no_gconf = rand()%10000; 
917                 show_new_vpn_ap = TRUE;
918                 
919         case VPN_ACCESS_POINT_SETTINGS:
920                 vpn_settings_screen(priv,ap_no_gconf,show_new_vpn_ap);
921         break;
922         case VPN_ACCESS_POINT_CONNECT:
923                         priv->connected_vpn_ap_gconf = ap_no_gconf;
924                         save_vpn_configuration(self,priv->connected_vpn_ap_gconf);
925                         vpngui_connect_dialog(GTK_BUTTON(priv->button2), self);
926         break;
927         case VPN_ACCESS_POINT_DELETE:
928         {
929                 delete_vpn_ap_settings(ap_no_gconf);    
930                 if(ap_no_gui == priv->connected_vpn_ap_ui)
931                 {
932                         priv->connected_vpn_ap_gconf = VPN_DEFAULT_HIRO_VPN;
933                         gtk_label_set_text(GTK_LABEL(priv->prof_name_label)," ");
934                         if(g_list_length(priv->list))
935                                 save_vpn_configuration(self,priv->connected_vpn_ap_gconf);
936                         else
937                         {
938                                 /* Disable the Connect Button, Delete Button,Settings Button */
939                                 gtk_widget_set_sensitive(priv->connect_button,FALSE);
940                                 gtk_widget_set_sensitive(priv->delete_button,FALSE);
941                                 gtk_widget_set_sensitive(priv->settings_button,FALSE);
942                         }
943                 }else if(ap_no_gui < priv->connected_vpn_ap_ui)
944                 {
945                         /* sometimes if configuration settings are done via schema, they do not get deleted.
946                          *  for this reason, we do this when list is populated.
947                          *  priv->connected_vpn_ap_ui--;
948                          *  */                  
949                 }
950         }
951         break;
952         default :
953         break;
954         }
955         
956 }
957 /**
958  * on_main_button_clicked:
959  *
960  * This function is called when the user clicks on the button added to the
961  * status menu. The function will properly start up the ui
962  * by showing the main dialog.
963  */
964 static void
965 on_main_button_clicked (
966                 GtkButton   *button,
967                 PluginInfo  *self)
968 {
969         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
970         
971         priv->main_dialog = GTK_DIALOG(hildon_dialog_new());
972         gtk_window_set_modal (GTK_WINDOW(priv->main_dialog), TRUE);
973         g_object_set (G_OBJECT(priv->main_dialog),
974                          "has-separator", FALSE,
975                          NULL);
976         gtk_window_set_title (GTK_WINDOW(priv->main_dialog),  "VPN Gateways");
977
978         GtkWidget * container_vbox  = gtk_vbox_new (FALSE, 0);
979         priv->list = get_vpn_config_list();
980         priv->total_items = g_list_length(priv->list);
981         
982         GtkWidget *scrolledwindow = hildon_pannable_area_new();
983         GtkWidget * radio_buttons_vbox  = gtk_vbox_new (FALSE, 0);
984         int i;
985         gboolean first_item = TRUE;
986         priv->connected_vpn_ap_ui = VPN_DEFAULT_HIRO_VPN;
987
988         for(i=0;i<priv->total_items;i++)
989         {
990                 vpn_data = ((struct VpnGuiListData*)g_list_nth_data(priv->list,i));
991                 if(!first_item)
992                 {
993                         vpn_data->radio_button = hildon_gtk_radio_button_new (HILDON_SIZE_FINGER_HEIGHT,
994                                         gtk_radio_button_group(GTK_RADIO_BUTTON(((struct VpnGuiListData*)g_list_nth_data(priv->list,0))->radio_button)));
995                         gtk_button_set_label (GTK_BUTTON (vpn_data->radio_button), vpn_data->vpn_name);
996                 }
997                 else
998                 {
999                         vpn_data->radio_button = hildon_gtk_radio_button_new (HILDON_SIZE_FINGER_HEIGHT,NULL);
1000                         gtk_button_set_label (GTK_BUTTON (vpn_data->radio_button), vpn_data->vpn_name);
1001                         first_item = FALSE;
1002                 }
1003                 
1004                 if(priv->connected_vpn_ap_gconf == vpn_data->ap_no)
1005                         priv->connected_vpn_ap_ui = i;
1006
1007                 
1008                 gtk_box_pack_start (GTK_BOX(radio_buttons_vbox),vpn_data->radio_button, TRUE, TRUE, 0);
1009                 
1010                 g_signal_connect_after (vpn_data->radio_button, "clicked",
1011                             G_CALLBACK (plugin_callback),
1012                             priv);                          
1013
1014         }
1015         hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(scrolledwindow),radio_buttons_vbox);                
1016         gtk_box_pack_start (GTK_BOX (container_vbox),scrolledwindow, TRUE, TRUE, 0);
1017         gtk_box_pack_start (GTK_BOX (priv->main_dialog->vbox),container_vbox, TRUE, TRUE, 0);
1018         
1019         gtk_dialog_add_button (priv->main_dialog,
1020                                   "New",VPN_ACCESS_POINT_NEW);
1021         priv->delete_button   = gtk_dialog_add_button (priv->main_dialog,
1022                                   "Delete",VPN_ACCESS_POINT_DELETE);
1023         priv->settings_button = gtk_dialog_add_button (priv->main_dialog,
1024                                   "Settings",VPN_ACCESS_POINT_SETTINGS);
1025         priv->connect_button  = gtk_dialog_add_button (priv->main_dialog,
1026                                   "Connect",VPN_ACCESS_POINT_CONNECT);
1027         g_signal_connect (G_OBJECT (priv->main_dialog),
1028                         "response",
1029                         G_CALLBACK(vpn_access_points_settings_dialog_response),
1030                         self);                  
1031         if(priv->total_items)
1032         {
1033                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(((struct VpnGuiListData*)g_list_nth_data(priv->list,priv->connected_vpn_ap_ui))->radio_button),TRUE);
1034                 plugin_callback(GTK_WIDGET(((struct VpnGuiListData*)g_list_nth_data(priv->list,priv->connected_vpn_ap_ui))->radio_button),priv);
1035         }
1036         else
1037         {
1038                 /* Disable the Connect Button, Delete Button,Settings Button */
1039                 gtk_widget_set_sensitive(priv->connect_button,FALSE);
1040                 gtk_widget_set_sensitive(priv->delete_button,FALSE);
1041                 gtk_widget_set_sensitive(priv->settings_button,FALSE);
1042         }
1043
1044         gtk_widget_show_all (GTK_WIDGET(priv->main_dialog));
1045
1046                    
1047 }
1048
1049 /* Save applet configs to file(s) */
1050 static void save_config(PrivateVpnDetails *vpn_settings,int ap_no)
1051 {
1052         GConfClient *gconf = NULL;
1053         g_debug("Executing %s", __PRETTY_FUNCTION__);
1054         
1055         g_return_if_fail(vpn_settings);
1056         /* Fetch the correct AP paths based on vpn_ap variable */
1057         vpn_make_config_paths(ap_no);
1058         gconf = gconf_client_get_default();
1059         if (vpn_settings->gwaddress) {
1060                 gconf_client_set_string(gconf, vpn_gconf_gwaddr,
1061                                 vpn_settings->gwaddress, NULL);
1062         }
1063         if (vpn_settings->group) {
1064                 gconf_client_set_string(gconf, vpn_gconf_group, vpn_settings->group, NULL);
1065         }
1066         if (vpn_settings->secret) {
1067                 gconf_client_set_string(gconf, vpn_gconf_secret, vpn_settings->secret, NULL);
1068         }
1069         gconf_client_set_bool(gconf, vpn_gconf_secret_obf, vpn_settings->secret_obf, NULL);
1070         if (vpn_settings->username) {
1071                 gconf_client_set_string(gconf, vpn_gconf_user, vpn_settings->username, NULL);
1072         }
1073         if (vpn_settings->vpn_name) {
1074                 gconf_client_set_string(gconf, vpn_gconf_vpn_name, vpn_settings->vpn_name, NULL);
1075         }
1076         
1077         if (vpn_settings->proxytype) {
1078                 gconf_client_set_string(gconf, vpn_gconf_proxy_mode, vpn_settings->proxytype, NULL);
1079         }
1080         if (vpn_settings->proxy_server) {               
1081                 gconf_client_set_string(gconf, vpn_gconf_proxy_server, vpn_settings->proxy_server, NULL);
1082         }
1083         if (vpn_settings->proxy_port) {
1084                 gconf_client_set_int(gconf, vpn_gconf_proxy_port, vpn_settings->proxy_port, NULL);
1085         }
1086         if (vpn_settings->proxy_autoconfig_url) {
1087                 gconf_client_set_string(gconf, vpn_gconf_proxy_autoconfig_url, vpn_settings->proxy_autoconfig_url, NULL);
1088         }
1089 /*
1090  *     if (vpn_settings->proxy_ignore_hosts) {
1091  *            gconf_client_set_list(gconf, vpn_gconf_proxy_ignore_hosts, GCONF_VALUE_STRING, vpn_settings->proxy_ignore_hosts, NULL);    
1092  *                }
1093  *                */
1094         g_object_unref(gconf);
1095         g_debug("Exiting %s", __PRETTY_FUNCTION__);
1096 }
1097
1098 static void set_proxy(PluginInfoPrivate *priv)
1099 {
1100         g_debug("Executing %s", __PRETTY_FUNCTION__);   
1101         if (! priv->vpn_settings.proxytype || g_str_equal(priv->vpn_settings.proxytype, "none")) {
1102                 return;
1103         }
1104         const gchar* proxy_server = (NULL == priv->vpn_settings.proxy_server) ? "" : priv->vpn_settings.proxy_server;
1105         GConfClient *gconf = gconf_client_get_default();
1106         GConfChangeSet *gcs = gconf_change_set_new();
1107         
1108         gconf_change_set_set_string(gcs, "/system/proxy/mode", priv->vpn_settings.proxytype);
1109         gconf_change_set_set_bool(gcs, "/system/http_proxy/use_http_proxy", TRUE);
1110         gconf_change_set_set_string(gcs, "/system/http_proxy/host", proxy_server);
1111         gconf_change_set_set_int(gcs, "/system/http_proxy/port", priv->vpn_settings.proxy_port);
1112         gconf_change_set_set_string(gcs, "/system/proxy/ftp_host", proxy_server);
1113         gconf_change_set_set_int(gcs, "/system/proxy/ftp_port", priv->vpn_settings.proxy_port);
1114         gconf_change_set_set_string(gcs, "/system/proxy/secure_host", proxy_server);
1115         gconf_change_set_set_int(gcs, "/system/proxy/secure_port", priv->vpn_settings.proxy_port);
1116         gconf_change_set_set_list(gcs, "/system/http_proxy/ignore_hosts", GCONF_VALUE_STRING, priv->vpn_settings.proxy_ignore_hosts);
1117         gconf_change_set_set_string(gcs, "/system/proxy/autoconfig_url", (NULL == priv->vpn_settings.proxy_autoconfig_url) ? "" : priv->vpn_settings.proxy_autoconfig_url);
1118         priv->vpn_settings.proxy_saved = gconf_client_reverse_change_set(gconf, gcs, NULL);
1119         gconf_client_commit_change_set(gconf, gcs, FALSE, NULL);
1120
1121         gconf_change_set_unref (gcs);
1122         g_object_unref(gconf);
1123         g_debug("Returning %s", __PRETTY_FUNCTION__);   
1124 }
1125
1126 static void restore_proxy(PluginInfoPrivate *priv)
1127 {
1128         g_debug("Executing %s", __PRETTY_FUNCTION__);
1129         if (g_str_equal(priv->vpn_settings.proxytype, "none")) {
1130                 return;
1131         }
1132         GConfClient *gconf = gconf_client_get_default();
1133         if(priv->vpn_settings.proxy_saved)
1134                 gconf_client_commit_change_set(gconf, priv->vpn_settings.proxy_saved, FALSE, NULL);
1135         
1136         g_object_unref(gconf);
1137         g_debug("Returning %s", __PRETTY_FUNCTION__);
1138 }
1139
1140 static gchar *iface_addr(const gchar *iface)
1141 {
1142         struct ifreq ifr;
1143         int fd = socket(AF_INET, SOCK_DGRAM, 0);
1144         if (fd < 0)
1145                 return NULL;
1146         strncpy(ifr.ifr_name, iface, sizeof ifr.ifr_name);
1147         if (ioctl(fd, SIOCGIFADDR, &ifr ) < 0) {
1148                 close(fd);
1149                 return NULL;
1150         }
1151         close(fd);
1152         return g_strdup(inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr));
1153 }
1154
1155 /* Run the vpnc command */
1156
1157 static gboolean do_connect(PluginInfo *self)
1158 {
1159         g_debug("Executing %s", __PRETTY_FUNCTION__);
1160         gboolean success = FALSE;
1161         
1162         if (vpnc_config_write(self)) {
1163                 success = vpnc_start(self);
1164         }
1165          /* FIXME: XXXX now that vpnc runs async, the unlink needs to be delayed
1166          *                       *      * until vpnc has had a chance to read it.. this needs to move elsewhere
1167          *                                               *           */
1168 #if 0
1169         unlink(priv->vpnc_config);
1170 #endif
1171         
1172         return success;
1173 }
1174
1175 /* Disconnect the VPN */
1176 static gboolean do_disconnect(PluginInfo *self, const gboolean forced)
1177 {
1178         g_debug("Executing %s, forced = %d", __PRETTY_FUNCTION__, forced);
1179         return vpnc_stop(self, forced);
1180 }
1181
1182
1183 void set_state(PluginInfo *self, int state)
1184 {
1185         PluginInfoPrivate   *priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
1186         g_debug("Executing %s, state = %d", __PRETTY_FUNCTION__, state);
1187         priv->state = state;
1188                         gchar *sip_command = NULL;
1189         switch (state) {
1190                 case VPN_CONNECTING:
1191                         gtk_widget_set_sensitive(priv->button, FALSE);
1192                         break;
1193                 case VPN_CONNECTED:
1194                         save_config(&priv->vpn_settings,priv->connected_vpn_ap_gconf);
1195                         set_proxy(priv);
1196                         hd_status_plugin_item_set_status_area_icon (
1197                                         HD_STATUS_PLUGIN_ITEM (self),
1198                                         priv->pixbuf[PIXBUF_ACTIVE_SMALL]);
1199                         priv->show_icon = TRUE;
1200                         gtk_image_set_from_pixbuf(GTK_IMAGE(priv->icon),
1201                                         priv->pixbuf[PIXBUF_ACTIVE]);
1202                         
1203                         isvpngui_connected = TRUE;
1204                         show_disconnect_button = TRUE;
1205                         show_settings = FALSE;
1206                         gtk_button_set_label (GTK_BUTTON(priv->button2),"Disconnect");
1207                         
1208                         gchar *addr = iface_addr("tun0");
1209                         g_object_set(priv->vpn_notify, "ip", addr, NULL);
1210                         /* Temporary hack for enalbing sip calls while connected via VPN */
1211                         sip_command = g_strdup_printf("for i in `run-standalone.sh mc-tool-hiro list` \n \
1212                                 do  \
1213                                 if [ \"`run-standalone.sh mc-tool-hiro show $i|grep Display|cut -f2 -d':'`\" == \" Nokia\" ];then \n\
1214                                         run-standalone.sh mc-tool-hiro request $i offline \n \
1215                                         run-standalone.sh mc-tool-hiro update $i string:local-ip-address=%s \n \
1216                                         run-standalone.sh mc-tool-hiro enable $i \n \
1217                                         sleep 1 \n \
1218                                         run-standalone.sh mc-tool-hiro request $i online \n \
1219                                 fi \n \
1220                                 done",addr);
1221                         system(sip_command);
1222                         if(sip_command)
1223                                 g_free(sip_command);
1224
1225                         gtk_widget_destroy(GTK_WIDGET(priv->banner));
1226                         hildon_banner_show_information(GTK_WIDGET(priv->button), NULL, "VPN activated.");
1227                         gtk_widget_set_sensitive(priv->button, TRUE);
1228                         
1229                         gchar *wlan_addr =NULL;
1230                         wlan_addr   = iface_addr("wlan0");
1231                         if(wlan_addr == NULL)   // if the connection is Point to Point Protocol
1232                                 wlan_addr   = iface_addr("ppp0");
1233                         if(wlan_addr == NULL)   // if the connection is 
1234                                 wlan_addr   = iface_addr("gprs0"); // 3G network
1235                         /*  if ip has changed, we are disconnecting */
1236                         if (priv->old_ip != NULL)
1237                         {
1238                                 if (strcmp(priv->old_ip, wlan_addr))
1239                                 {
1240                                         
1241                                         strcpy(priv->old_ip, wlan_addr);
1242                                         if(addr != NULL)
1243                                         {
1244                                                 g_free(addr);
1245                                                 addr = NULL;
1246                                         }
1247                                         if(wlan_addr!= NULL)
1248                                         {
1249                                                 g_free(wlan_addr);
1250                                                 wlan_addr = NULL;
1251                                         }
1252                                         do_disconnect(self, FALSE);
1253                                 }
1254                         }
1255                         else
1256                         {
1257                                 priv->old_ip = g_malloc((strlen(wlan_addr) + 2) * sizeof(gchar));
1258                                 strcpy(priv->old_ip, wlan_addr);
1259                         }
1260                         if(addr != NULL)
1261                         {
1262                                 g_free(addr);
1263                                 addr = NULL;
1264                         }
1265                         if(wlan_addr != NULL)
1266                         {
1267                                 g_free(wlan_addr);
1268                                 wlan_addr = NULL;
1269                         }
1270                         
1271                         break;
1272                 case VPN_FORCED_DISCONNECTING:
1273
1274                         priv->show_connect_dialog = TRUE;
1275                         if(priv->old_ip != NULL)
1276                         {
1277                                 g_free(priv->old_ip);
1278                                 priv->old_ip = NULL;
1279                         }
1280                 case VPN_DISCONNECTING:
1281                         if(priv->old_ip != NULL)
1282                         {
1283                                 g_free(priv->old_ip);
1284                                 priv->old_ip = NULL;
1285                         }
1286                         gtk_widget_set_sensitive(priv->button, FALSE);
1287                         priv->banner = hildon_banner_show_animation (
1288                                         GTK_WIDGET(priv->button), NULL, "Disconnecting...");
1289                         break;
1290                 case VPN_CONNECT_FAILED:
1291                         gtk_widget_destroy(GTK_WIDGET(priv->banner));
1292                         priv->state = VPN_DISCONNECTED;
1293                         hildon_banner_show_information(GTK_WIDGET(priv->button),
1294                                         NULL, "Connecting failed");
1295                         gtk_widget_set_sensitive(priv->button, TRUE);
1296                         restore_proxy(priv);
1297                         break;
1298                 case VPN_DISCONNECTED:
1299                         
1300                         hd_status_plugin_item_set_status_area_icon (
1301                                         HD_STATUS_PLUGIN_ITEM (self),
1302                                         NULL);
1303                         priv->show_icon = FALSE;
1304                                           
1305                         gtk_image_set_from_pixbuf(GTK_IMAGE(priv->icon),
1306                                         priv->pixbuf[PIXBUF_INACTIVE]);
1307                         if(priv->old_ip != NULL)
1308                         {
1309                                 g_free(priv->old_ip);
1310                                 priv->old_ip = NULL;
1311                         }
1312                         restore_proxy(priv);
1313                         isvpngui_connected = FALSE;
1314                         show_disconnect_button = FALSE;
1315                         show_settings = TRUE;
1316                         gtk_button_set_label (GTK_BUTTON(priv->button2),"Connect");
1317                         gtk_widget_destroy(GTK_WIDGET(priv->banner));
1318                         hildon_banner_show_information(GTK_WIDGET(priv->button),
1319                                         NULL, "VPN disconnected.");
1320                         gtk_widget_set_sensitive(priv->button, TRUE);
1321                         
1322                         g_object_set(priv->vpn_notify, "ip", "", NULL);
1323
1324                         // have to remove this hack ..
1325                         sip_command = g_strdup_printf("for i in `run-standalone.sh mc-tool-hiro list` \n \
1326                                 do  \
1327                                 if [ \"`run-standalone.sh mc-tool-hiro show $i|grep Display|cut -f2 -d':'`\" == \" Nokia\" ];then \n\
1328                                         run-standalone.sh mc-tool-hiro request $i offline \n \
1329                                         run-standalone.sh mc-tool-hiro update $i clear:local-ip-address \n \
1330                                         run-standalone.sh mc-tool-hiro enable $i \n \
1331                                         sleep 1 \n \
1332                                         run-standalone.sh mc-tool-hiro request $i online \n \
1333                                 fi \n \
1334                                 done");
1335                         system(sip_command);
1336                         if(sip_command)
1337                                 g_free(sip_command);
1338                         break;
1339                 default:
1340 //                      error_msg("Unknown state request %d", state);
1341                         g_debug("Unknown state request %d", state);
1342                         break;
1343         }
1344         g_debug("Exiting %s, state = %d", __PRETTY_FUNCTION__, state);
1345 }
1346
1347 static void vpngui_connect_dialog( GtkButton   *button,
1348                                 PluginInfo  *self)
1349 {
1350         PluginInfoPrivate *priv;
1351         GtkDialog *dialog;
1352         g_debug("Executing %s", __PRETTY_FUNCTION__);
1353         priv = VPNGUI_PLUGIN_GET_PRIVATE (self);
1354         GtkWidget           *parent = NULL;
1355         parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
1356         gtk_widget_hide(parent);
1357         if(show_settings)
1358         {
1359                 if(priv->vpn_notify == NULL)
1360                 {
1361                         hildon_banner_show_animation (NULL, NULL, "You have to REBOOT the device once installation of vpn is done");
1362                         return;
1363                 }
1364                 GtkWidget *generic_label;
1365                 GtkWidget *container_hbox, *container_vbox;
1366                 GtkWidget *username_entry, *passwd_entry;
1367                 
1368                 if (ensure_network(self) == FALSE || priv->have_network == FALSE) {
1369                         error_msg("Setting up network connection failed");
1370                         hildon_banner_show_information(NULL, NULL, "Setting up network connection failed");
1371                         return;
1372                 }       
1373                 
1374                 dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("VPN Authentication",
1375                                         NULL,
1376                                         GTK_DIALOG_MODAL,
1377                                         GTK_STOCK_OK,
1378                                         GTK_RESPONSE_OK,
1379                                         GTK_STOCK_CANCEL,
1380                                         GTK_RESPONSE_REJECT,
1381                                         NULL));
1382                 container_hbox = gtk_hbox_new(FALSE, 0);
1383                 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), container_hbox);
1384                 container_vbox = gtk_vbox_new(FALSE, 0);
1385                 gtk_box_pack_start(GTK_BOX(container_hbox), container_vbox, FALSE, FALSE, 6);
1386                 generic_label = gtk_label_new("Username:");
1387                 gtk_container_add(GTK_CONTAINER(container_vbox), generic_label);
1388                 generic_label = gtk_label_new("Password");
1389                 gtk_container_add(GTK_CONTAINER(container_vbox), generic_label);
1390                 container_vbox = gtk_vbox_new(FALSE, 0);
1391                 gtk_box_pack_start(GTK_BOX(container_hbox), container_vbox, FALSE, FALSE, 6);
1392                 
1393                 username_entry = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
1394                 gchar* username =NULL;
1395                 hildon_gtk_entry_set_input_mode (GTK_ENTRY(username_entry),  HILDON_GTK_INPUT_MODE_FULL);
1396                 if (priv->vpn_settings.username) {
1397                         username = g_strdup(priv->vpn_settings.username);
1398                         gtk_entry_set_text(GTK_ENTRY(username_entry), username);
1399                 }
1400                 gtk_container_add(GTK_CONTAINER(container_vbox), username_entry);
1401                 passwd_entry = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT);
1402                 gtk_entry_set_activates_default(GTK_ENTRY(passwd_entry), TRUE);
1403                 hildon_gtk_entry_set_input_mode (GTK_ENTRY(passwd_entry), HILDON_GTK_INPUT_MODE_NUMERIC | HILDON_GTK_INPUT_MODE_INVISIBLE);
1404                 gtk_container_add(GTK_CONTAINER(container_vbox), passwd_entry);
1405                 if (priv->vpn_settings.username) {
1406                         gtk_widget_grab_focus(GTK_WIDGET(passwd_entry));
1407                 }
1408                 gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK);
1409                 gtk_widget_show_all(GTK_WIDGET(dialog));
1410         
1411                 if (gtk_dialog_run(dialog) == GTK_RESPONSE_OK) {
1412                         priv->vpn_settings.username = g_strdup(gtk_entry_get_text(GTK_ENTRY(username_entry)));
1413                         priv->vpn_settings.password = g_strdup(gtk_entry_get_text(GTK_ENTRY(passwd_entry)));
1414                         if(!strcmp(priv->vpn_settings.password,""))  //for empty password
1415                         {
1416                                 hildon_banner_show_information(GTK_WIDGET(priv->button),
1417                                                 NULL, "Password is Empty");
1418                                 if(username)
1419                                         g_free(username);
1420                                 gtk_widget_destroy(GTK_WIDGET(dialog));
1421                                 return;
1422                         }
1423                         priv->banner = hildon_banner_show_animation (GTK_WIDGET(parent),
1424                                         NULL, "Connecting...");
1425                         do_connect(self);
1426                 }
1427                 
1428                 if(username)
1429                         g_free(username);
1430                 gtk_widget_destroy(GTK_WIDGET(dialog));
1431         }
1432         else
1433         {
1434                 dialog = GTK_DIALOG(hildon_note_new_confirmation(NULL,
1435                                         (gchar*)"Disconnect VPN?"));
1436                 if (gtk_dialog_run(dialog) == GTK_RESPONSE_OK) {
1437                         do_disconnect(self, FALSE);
1438                 }
1439                 gtk_widget_destroy(GTK_WIDGET(dialog));
1440         }
1441 }
1442