Release tizen_2.0_beta
[framework/connectivity/connman.git] / plugins / openconnect.c
index f0d39a1..cf3bcd9 100644 (file)
 #include <config.h>
 #endif
 
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <net/if.h>
+
+#include <glib.h>
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/plugin.h>
 #include <connman/provider.h>
 #include <connman/log.h>
 #include <connman/task.h>
+#include <connman/ipconfig.h>
 
 #include "vpn.h"
 
 static int oc_notify(DBusMessage *msg, struct connman_provider *provider)
 {
        DBusMessageIter iter, dict;
-       struct oc_data *data;
        const char *reason, *key, *value;
        const char *domain = NULL;
+       char *addressv4 = NULL, *addressv6 = NULL;
+       char *netmask = NULL, *gateway = NULL;
+       unsigned char prefix_len = 0;
+       struct connman_ipaddress *ipaddress;
 
        dbus_message_iter_init(msg, &iter);
 
@@ -52,12 +60,6 @@ static int oc_notify(DBusMessage *msg, struct connman_provider *provider)
                return VPN_STATE_FAILURE;
        }
 
-       data = connman_provider_get_data(provider);
-       if (!data) {
-               DBG("provider %p no data", provider);
-               return VPN_STATE_FAILURE;
-       }
-
        if (strcmp(reason, "connect"))
                return VPN_STATE_DISCONNECT;
 
@@ -77,27 +79,82 @@ static int oc_notify(DBusMessage *msg, struct connman_provider *provider)
                        DBG("%s = %s", key, value);
 
                if (!strcmp(key, "VPNGATEWAY"))
-                       connman_provider_set_string(provider, "Gateway", value);
+                       gateway = g_strdup(value);
 
                if (!strcmp(key, "INTERNAL_IP4_ADDRESS"))
-                       connman_provider_set_string(provider, "Address", value);
+                       addressv4 = g_strdup(value);
+
+               if (!strcmp(key, "INTERNAL_IP6_ADDRESS")) {
+                       addressv6 = g_strdup(value);
+                       prefix_len = 128;
+               }
 
                if (!strcmp(key, "INTERNAL_IP4_NETMASK"))
-                       connman_provider_set_string(provider, "Netmask", value);
+                       netmask = g_strdup(value);
+
+               if (!strcmp(key, "INTERNAL_IP6_NETMASK")) {
+                       char *sep;
+
+                       /* The netmask contains the address and the prefix */
+                       sep = strchr(value, '/');
+                       if (sep != NULL) {
+                               unsigned char ip_len = sep - value;
 
-               if (!strcmp(key, "INTERNAL_IP4_DNS"))
-                       connman_provider_set_string(provider, "DNS", value);
+                               addressv6 = g_strndup(value, ip_len);
+                               prefix_len = (unsigned char)
+                                               strtol(sep + 1, NULL, 10);
+                       }
+               }
+
+               if (!strcmp(key, "INTERNAL_IP4_DNS") ||
+                               !strcmp(key, "INTERNAL_IP6_DNS"))
+                       connman_provider_set_nameservers(provider, value);
 
                if (!strcmp(key, "CISCO_PROXY_PAC"))
-                       connman_provider_set_string(provider, "PAC", value);
+                       connman_provider_set_pac(provider, value);
 
                if (domain == NULL && !strcmp(key, "CISCO_DEF_DOMAIN"))
                        domain = value;
 
+               if (g_str_has_prefix(key, "CISCO_SPLIT_INC") == TRUE ||
+                       g_str_has_prefix(key, "CISCO_IPV6_SPLIT_INC") == TRUE)
+                       connman_provider_append_route(provider, key, value);
+
                dbus_message_iter_next(&dict);
        }
 
-       connman_provider_set_string(provider, "Domain", domain);
+       DBG("%p %p", addressv4, addressv6);
+
+       if (addressv4 != NULL)
+               ipaddress = connman_ipaddress_alloc(AF_INET);
+       else if (addressv6 != NULL)
+               ipaddress = connman_ipaddress_alloc(AF_INET6);
+       else
+               ipaddress = NULL;
+
+       if (ipaddress == NULL) {
+               g_free(addressv4);
+               g_free(addressv6);
+               g_free(netmask);
+               g_free(gateway);
+
+               return VPN_STATE_FAILURE;
+       }
+
+       if (addressv4 != NULL)
+               connman_ipaddress_set_ipv4(ipaddress, addressv4,
+                                               netmask, gateway);
+       else
+               connman_ipaddress_set_ipv6(ipaddress, addressv6,
+                                               prefix_len, gateway);
+       connman_provider_set_ipaddress(provider, ipaddress);
+       connman_provider_set_domain(provider, domain);
+
+       g_free(addressv4);
+       g_free(addressv6);
+       g_free(netmask);
+       g_free(gateway);
+       connman_ipaddress_free(ipaddress);
 
        return VPN_STATE_CONNECT;
 }
@@ -124,7 +181,7 @@ static int oc_connect(struct connman_provider *provider,
                                                "OpenConnect.ServerCert");
        if (certsha1)
                connman_task_add_argument(task, "--servercert",
-                                         (char *)certsha1);
+                                                       (char *)certsha1);
 
        cafile = connman_provider_get_string(provider, "OpenConnect.CACert");
        mtu = connman_provider_get_string(provider, "VPN.MTU");
@@ -162,9 +219,52 @@ static int oc_connect(struct connman_provider *provider,
        return 0;
 }
 
+static int oc_save (struct connman_provider *provider, GKeyFile *keyfile)
+{
+       const char *setting;
+
+       setting = connman_provider_get_string(provider,
+                                       "OpenConnect.ServerCert");
+       if (setting != NULL)
+               g_key_file_set_string(keyfile,
+                               connman_provider_get_save_group(provider),
+                               "OpenConnect.ServerCert", setting);
+
+       setting = connman_provider_get_string(provider,
+                                       "OpenConnect.CACert");
+       if (setting != NULL)
+               g_key_file_set_string(keyfile,
+                               connman_provider_get_save_group(provider),
+                               "OpenConnect.CACert", setting);
+
+       setting = connman_provider_get_string(provider,
+                                       "VPN.MTU");
+       if (setting != NULL)
+               g_key_file_set_string(keyfile,
+                               connman_provider_get_save_group(provider),
+                               "VPN.MTU", setting);
+
+       return 0;
+}
+
+static int oc_error_code(int exit_code)
+{
+
+       switch (exit_code) {
+       case 1:
+               return CONNMAN_PROVIDER_ERROR_CONNECT_FAILED;
+       case 2:
+               return CONNMAN_PROVIDER_ERROR_LOGIN_FAILED;
+       default:
+               return CONNMAN_PROVIDER_ERROR_UNKNOWN;
+       }
+}
+
 static struct vpn_driver vpn_driver = {
        .notify         = oc_notify,
        .connect        = oc_connect,
+       .error_code     = oc_error_code,
+       .save           = oc_save,
 };
 
 static int openconnect_init(void)