2 * This file is part of vpngui
4 * Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies)
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.
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.
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
29 /* these are pretty much copy-pasted from networkmanager-vpnc... */
31 static void vpnc_watch_cb(GPid pid, gint status, gpointer data)
34 g_return_if_fail(data);
35 info = (PluginInfo *)data;
38 PluginInfoPrivate *priv = VPNGUI_PLUGIN_GET_PRIVATE (info);
39 gboolean forced_disconnection = (VPN_FORCED_DISCONNECTING == priv->state);
41 g_debug("Executing %s", __PRETTY_FUNCTION__);
45 /* if we get here during connecting things went foobar... */
46 set_state(info, VPN_CONNECT_FAILED);
48 case VPN_DISCONNECTING:
49 case VPN_FORCED_DISCONNECTING:
50 set_state(info, VPN_DISCONNECTED);
52 case VPN_DISCONNECTED:
55 set_state(info, VPN_DISCONNECTED);
57 if(!forced_disconnection) {
58 if (WIFEXITED(status)) {
59 error = WEXITSTATUS(status);
62 // Nasty hack: vpnc 0.5.1 returns with code 256 on erroneous auth.
63 // but maybe it returns with 256 on other cases to.
64 /// @todo Check vpnc errorcodes.
65 if ( status == 256 ) errmsg = NULL;//g_strdup_printf("Authentication failed");
67 errmsg = g_strdup_printf("Vpnc exited with error code %d\n", status);
70 } else if (WIFSTOPPED(status)) {
71 errmsg = g_strdup_printf("Vpnc was stopped unexpectedly");
72 } else if (WIFSIGNALED(status)) {
73 errmsg = g_strdup_printf("Vpnc died from signal %d", WTERMSIG (status));
75 errmsg = g_strdup_printf("Vpnc died under suspicious circumstances");
78 g_spawn_close_pid(priv->vpnc_pid);
84 error_msg("Authentication failed");
88 error_msg("Error:\n%s", errmsg);
97 g_debug("Exiting %s", __PRETTY_FUNCTION__);
100 gboolean vpnc_start(PluginInfo *info)
103 GPtrArray *vpnc_argv;
104 GError *error = NULL;
107 g_debug("Executing %s", __PRETTY_FUNCTION__);
109 g_return_val_if_fail (info != NULL, FALSE);
111 PluginInfoPrivate *priv = VPNGUI_PLUGIN_GET_PRIVATE (info);
115 vpnc_argv = g_ptr_array_new();
116 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/bin/sudo");
117 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/sbin/vpngui-helper");
118 g_ptr_array_add (vpnc_argv, (gpointer) "connect");
119 g_ptr_array_add (vpnc_argv, (gpointer) "--non-inter");
120 g_ptr_array_add (vpnc_argv, (gpointer) "--no-detach");
121 g_ptr_array_add (vpnc_argv, (gpointer) priv->vpnc_config);
122 g_ptr_array_add (vpnc_argv, NULL);
124 if (!g_spawn_async_with_pipes (NULL, (char **) vpnc_argv->pdata, NULL,
125 G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &stdin_fd,
126 NULL, NULL, &error)) {
127 g_ptr_array_free (vpnc_argv, TRUE);
128 error_msg("vpnc failed to start: %s\n", error->message);
133 g_ptr_array_free (vpnc_argv, TRUE);
135 g_debug("%s: vpnc started with pid %d", __PRETTY_FUNCTION__, pid);
136 set_state(info, VPN_CONNECTING);
138 vpnc_watch = g_child_watch_source_new (pid);
139 g_source_set_callback (vpnc_watch, (GSourceFunc) vpnc_watch_cb, info, NULL);
141 g_source_attach (vpnc_watch, NULL);
143 priv->vpnc_pid = pid;
144 priv->vpnc_watch_id = g_source_get_id(vpnc_watch);
146 g_source_unref (vpnc_watch);
147 g_debug("Exiting %s", __PRETTY_FUNCTION__);
152 * start the vpnc killer - we'll get notified of vpnc actually
153 * dying elsewhere so we don't care about the results here
155 gboolean vpnc_stop(PluginInfo *info, const gboolean forced)
157 GPtrArray *vpnc_argv;
158 GError *error = NULL;
161 g_debug("Executing %s, forced = %d", __PRETTY_FUNCTION__, forced);
163 g_return_val_if_fail (info != NULL, FALSE);
164 PluginInfoPrivate *priv = VPNGUI_PLUGIN_GET_PRIVATE (info);
166 if (priv->vpnc_pid == 0) {
170 pid = g_strdup_printf("%d", priv->vpnc_pid);
172 vpnc_argv = g_ptr_array_new();
173 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/bin/sudo");
174 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/sbin/vpngui-helper");
175 g_ptr_array_add (vpnc_argv, (gpointer) "disconnect");
176 g_ptr_array_add (vpnc_argv, (gpointer) pid);
177 g_ptr_array_add (vpnc_argv, NULL);
179 if (!g_spawn_async(NULL, (char **) vpnc_argv->pdata, NULL,
180 0, NULL, NULL, NULL, &error)) {
181 g_ptr_array_free (vpnc_argv, TRUE);
182 error_msg("vpn disconnect failed to start: %s\n", error->message);
187 set_state(info, forced ? VPN_FORCED_DISCONNECTING : VPN_DISCONNECTING);
189 /* unregister the vpnc watcher, we'll get notified by dbus on disconnect */
190 // g_source_remove(info->vpnc_watch_id);
191 // info->vpnc_watch_id = 0;
193 g_ptr_array_free (vpnc_argv, TRUE);
199 gboolean vpnc_restart(PluginInfo *info)
201 GPtrArray *vpnc_argv;
202 GError *error = NULL;
205 g_debug("Executing %s", __PRETTY_FUNCTION__);
207 g_return_val_if_fail (info != NULL, FALSE);
208 PluginInfoPrivate *priv = VPNGUI_PLUGIN_GET_PRIVATE (info);
210 if (priv->vpnc_pid == 0) {
214 pid = g_strdup_printf("%d", priv->vpnc_pid);
216 vpnc_argv = g_ptr_array_new();
217 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/bin/sudo");
218 g_ptr_array_add (vpnc_argv, (gpointer) "/usr/sbin/vpngui-helper");
219 g_ptr_array_add (vpnc_argv, (gpointer) "reconnect");
220 g_ptr_array_add (vpnc_argv, (gpointer) pid);
221 g_ptr_array_add (vpnc_argv, NULL);
223 if (!g_spawn_async(NULL, (char **) vpnc_argv->pdata, NULL,
224 0, NULL, NULL, NULL, &error)) {
225 g_ptr_array_free (vpnc_argv, TRUE);
226 error_msg("vpn disconnect failed to start: %s\n", error->message);
232 g_ptr_array_free (vpnc_argv, TRUE);
238 /* Write out the temporary vpnc config-file */
239 gboolean vpnc_config_write(PluginInfo *info)
241 g_debug("Executing %s", __PRETTY_FUNCTION__);
243 char tmp[] = "/tmp/vpnc.XXXXXX";
245 PluginInfoPrivate *priv = VPNGUI_PLUGIN_GET_PRIVATE (info);
247 if (mkstemp(tmp) < 0) {
250 priv->vpnc_config = strdup(tmp);
251 config = fopen(priv->vpnc_config, "w+");
256 fprintf(config, "Debug 2\n");
257 fprintf(config, "IPSec gateway %s\n", priv->vpn_settings.gwaddress);
258 fprintf(config, "IPSec ID %s\n", priv->vpn_settings.group);
259 if (priv->vpn_settings.secret_obf) {
260 fprintf(config, "IPSec obfuscated secret %s\n", priv->vpn_settings.secret);
262 fprintf(config, "IPSec secret %s\n", priv->vpn_settings.secret);
264 fprintf(config, "Xauth username %s\n", priv->vpn_settings.username);
265 fprintf(config, "Xauth password %s\n", priv->vpn_settings.password);
267 fprintf(config, "Rekeying interval %d\n", priv->vpn_settings.rekeyinterval);
268 fprintf(config, "NAT-Keepalive packet interval %d\n", priv->vpn_settings.natkeepalive);
273 // vim:ts=4:sw=4:sts=4