static int run_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name, vpn_provider_connect_cb_t cb, void *user_data) { const char *vpnhost, *vpncookie, *servercert, *mtu; int fd, err = 0, len; vpnhost = vpn_provider_get_string(provider, "OpenConnect.VPNHost"); if (vpnhost == NULL) vpnhost = vpn_provider_get_string(provider, "Host"); vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie"); servercert = vpn_provider_get_string(provider, "OpenConnect.ServerCert"); if (vpncookie == NULL || servercert == NULL) { err = -EINVAL; goto done; } task_append_config_data(provider, task); connman_task_add_argument(task, "--servercert", servercert); mtu = vpn_provider_get_string(provider, "VPN.MTU"); if (mtu != NULL) connman_task_add_argument(task, "--mtu", (char *)mtu); connman_task_add_argument(task, "--syslog", NULL); connman_task_add_argument(task, "--cookie-on-stdin", NULL); connman_task_add_argument(task, "--script", SCRIPTDIR "/openconnect-script"); connman_task_add_argument(task, "--interface", if_name); connman_task_add_argument(task, (char *)vpnhost, NULL); err = connman_task_run(task, vpn_died, provider, &fd, NULL, NULL); if (err < 0) { connman_error("openconnect failed to start"); err = -EIO; goto done; } len = strlen(vpncookie); if (write(fd, vpncookie, len) != (ssize_t)len || write(fd, "\n", 1) != 1) { connman_error("openconnect failed to take cookie on stdin"); err = -EIO; goto done; } done: if (cb != NULL) cb(provider, user_data, err); return err; }
static int oc_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *setting; setting = vpn_provider_get_string(provider, "OpenConnect.ServerCert"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "OpenConnect.ServerCert", setting); setting = vpn_provider_get_string(provider, "OpenConnect.CACert"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "OpenConnect.CACert", setting); setting = vpn_provider_get_string(provider, "VPN.MTU"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "VPN.MTU", setting); return 0; }
static DBusMessage *l2tp_get_sec(struct connman_task *task, DBusMessage *msg, void *user_data) { const char *user, *passwd; struct vpn_provider *provider = user_data; if (!dbus_message_get_no_reply(msg)) { DBusMessage *reply; user = vpn_provider_get_string(provider, "L2TP.User"); passwd = vpn_provider_get_string(provider, "L2TP.Password"); if (!user || strlen(user) == 0 || !passwd || strlen(passwd) == 0) return NULL; reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_append_args(reply, DBUS_TYPE_STRING, &user, DBUS_TYPE_STRING, &passwd, DBUS_TYPE_INVALID); return reply; } return NULL; }
static int oc_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name) { const char *vpnhost, *vpncookie, *cafile, *certsha1, *mtu; int fd, err; vpnhost = vpn_provider_get_string(provider, "Host"); if (!vpnhost) { connman_error("Host not set; cannot enable VPN"); return -EINVAL; } vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie"); if (!vpncookie) { connman_error("OpenConnect.Cookie not set; cannot enable VPN"); return -EINVAL; } certsha1 = vpn_provider_get_string(provider, "OpenConnect.ServerCert"); if (certsha1) connman_task_add_argument(task, "--servercert", (char *)certsha1); cafile = vpn_provider_get_string(provider, "OpenConnect.CACert"); mtu = vpn_provider_get_string(provider, "VPN.MTU"); if (cafile) connman_task_add_argument(task, "--cafile", (char *)cafile); if (mtu) connman_task_add_argument(task, "--mtu", (char *)mtu); connman_task_add_argument(task, "--syslog", NULL); connman_task_add_argument(task, "--cookie-on-stdin", NULL); connman_task_add_argument(task, "--script", SCRIPTDIR "/openconnect-script"); connman_task_add_argument(task, "--interface", if_name); connman_task_add_argument(task, (char *)vpnhost, NULL); err = connman_task_run(task, vpn_died, provider, &fd, NULL, NULL); if (err < 0) { connman_error("openconnect failed to start"); return -EIO; } if (write(fd, vpncookie, strlen(vpncookie)) != (ssize_t)strlen(vpncookie) || write(fd, "\n", 1) != 1) { connman_error("openconnect failed to take cookie on stdin"); return -EIO; } return 0; }
static int vc_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name, vpn_provider_connect_cb_t cb, const char *dbus_sender, void *user_data) { const char *option; int err = 0, fd; option = vpn_provider_get_string(provider, "Host"); if (!option) { connman_error("Host not set; cannot enable VPN"); err = -EINVAL; goto done; } option = vpn_provider_get_string(provider, "VPNC.IPSec.ID"); if (!option) { connman_error("Group not set; cannot enable VPN"); err = -EINVAL; goto done; } connman_task_add_argument(task, "--non-inter", NULL); connman_task_add_argument(task, "--no-detach", NULL); connman_task_add_argument(task, "--ifname", if_name); connman_task_add_argument(task, "--ifmode", "tun"); connman_task_add_argument(task, "--script", SCRIPTDIR "/openconnect-script"); option = vpn_provider_get_string(provider, "VPNC.Debug"); if (option) connman_task_add_argument(task, "--debug", option); connman_task_add_argument(task, "-", NULL); err = connman_task_run(task, vpn_died, provider, &fd, NULL, NULL); if (err < 0) { connman_error("vpnc failed to start"); err = -EIO; goto done; } err = vc_write_config_data(provider, fd); close(fd); done: if (cb) cb(provider, user_data, err); return err; }
static int pptp_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name, vpn_provider_connect_cb_t cb, const char *dbus_sender, void *user_data) { const char *username, *password; int err; DBG("iface %s provider %p user %p", if_name, provider, user_data); if (connman_task_set_notify(task, "getsec", pptp_get_sec, provider)) { err = -ENOMEM; goto error; } username = vpn_provider_get_string(provider, "PPTP.User"); password = vpn_provider_get_string(provider, "PPTP.Password"); DBG("user %s password %p", username, password); if (!username || !password) { struct pptp_private_data *data; data = g_try_new0(struct pptp_private_data, 1); if (!data) return -ENOMEM; data->task = task; data->if_name = g_strdup(if_name); data->cb = cb; data->user_data = user_data; err = request_input(provider, request_input_cb, dbus_sender, data); if (err != -EINPROGRESS) { free_private_data(data); goto done; } return err; } done: return run_connect(provider, task, if_name, cb, user_data, username, password); error: if (cb) cb(provider, user_data, err); return err; }
static int l2tp_write_fields(struct vpn_provider *provider, int fd, int sub) { int i; const char *opt_s; for (i = 0; i < (int)ARRAY_SIZE(pppd_options); i++) { if (pppd_options[i].sub != sub) continue; opt_s = vpn_provider_get_string(provider, pppd_options[i].cm_opt); if (!opt_s) opt_s = pppd_options[i].vpn_default; if (!opt_s) continue; if (pppd_options[i].type == OPT_STRING) l2tp_write_section(fd, pppd_options[i].pppd_opt, opt_s); else if (pppd_options[i].type == OPT_BOOL) l2tp_write_bool_option(fd, pppd_options[i].pppd_opt, opt_s); } return 0; }
static int vc_write_config_data(struct vpn_provider *provider, int fd) { const char *opt_s; int i; for (i = 0; i < (int)ARRAY_SIZE(vpnc_options); i++) { opt_s = vpn_provider_get_string(provider, vpnc_options[i].cm_opt); if (!opt_s) opt_s = vpnc_options[i].vpnc_default; if (!opt_s) continue; if (vpnc_options[i].type == OPT_STRING) { if (write_option(fd, vpnc_options[i].vpnc_opt, opt_s) < 0) return -EIO; } else if (vpnc_options[i].type == OPT_BOOLEAN) { if (write_bool_option(fd, vpnc_options[i].vpnc_opt, opt_s) < 0) return -EIO; } } return 0; }
static int l2tp_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *option; bool l2tp_option, pppd_option; int i; for (i = 0; i < (int)ARRAY_SIZE(pppd_options); i++) { l2tp_option = pppd_option = false; if (strncmp(pppd_options[i].cm_opt, "L2TP.", 5) == 0) l2tp_option = true; if (strncmp(pppd_options[i].cm_opt, "PPPD.", 5) == 0) pppd_option = true; if (l2tp_option || pppd_option) { option = vpn_provider_get_string(provider, pppd_options[i].cm_opt); if (!option) { /* * Check if the option prefix is L2TP as the * PPPD options were using L2TP prefix earlier. */ char *l2tp_str; if (!pppd_option) continue; l2tp_str = g_strdup_printf("L2TP.%s", &pppd_options[i].cm_opt[5]); option = vpn_provider_get_string(provider, l2tp_str); g_free(l2tp_str); if (!option) continue; } g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), pppd_options[i].cm_opt, option); } } return 0; }
static int oc_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *setting, *option; int i; setting = vpn_provider_get_string(provider, "OpenConnect.ServerCert"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "OpenConnect.ServerCert", setting); setting = vpn_provider_get_string(provider, "OpenConnect.CACert"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "OpenConnect.CACert", setting); setting = vpn_provider_get_string(provider, "VPN.MTU"); if (setting != NULL) g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), "VPN.MTU", setting); for (i = 0; i < (int)ARRAY_SIZE(oc_options); i++) { if (strncmp(oc_options[i].cm_opt, "OpenConnect.", 12) == 0) { option = vpn_provider_get_string(provider, oc_options[i].cm_opt); if (option == NULL) continue; g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), oc_options[i].cm_opt, option); } } return 0; }
static int oc_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name, vpn_provider_connect_cb_t cb, void *user_data) { const char *vpnhost, *vpncookie, *servercert; int err; vpnhost = vpn_provider_get_string(provider, "Host"); if (vpnhost == NULL) { connman_error("Host not set; cannot enable VPN"); return -EINVAL; } vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie"); servercert = vpn_provider_get_string(provider, "OpenConnect.ServerCert"); if (vpncookie == NULL || servercert == NULL) { struct oc_private_data *data; data = g_try_new0(struct oc_private_data, 1); if (data == NULL) return -ENOMEM; data->provider = provider; data->task = task; data->if_name = g_strdup(if_name); data->cb = cb; data->user_data = user_data; err = request_cookie_input(provider, data); if (err != -EINPROGRESS) { vpn_provider_indicate_error(data->provider, VPN_PROVIDER_ERROR_LOGIN_FAILED); free_private_data(data); } return err; } return run_connect(provider, task, if_name, cb, user_data); }
static int ov_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *option; int i; for (i = 0; i < (int)ARRAY_SIZE(ov_options); i++) { if (strncmp(ov_options[i].cm_opt, "OpenVPN.", 8) == 0) { option = vpn_provider_get_string(provider, ov_options[i].cm_opt); if (option == NULL) continue; g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), ov_options[i].cm_opt, option); } } return 0; }
static int vc_device_flags(struct vpn_provider *provider) { const char *option; option = vpn_provider_get_string(provider, "VPNC.DeviceType"); if (!option) { return IFF_TUN; } if (g_str_equal(option, "tap")) { return IFF_TAP; } if (!g_str_equal(option, "tun")) { connman_warn("bad VPNC.DeviceType value, falling back to tun"); } return IFF_TUN; }
static int l2tp_write_config(struct vpn_provider *provider, const char *pppd_name, int fd) { const char *option; l2tp_write_option(fd, "[global]", NULL); l2tp_write_fields(provider, fd, OPT_L2G); l2tp_write_option(fd, "[lac l2tp]", NULL); option = vpn_provider_get_string(provider, "Host"); l2tp_write_option(fd, "lns =", option); l2tp_write_fields(provider, fd, OPT_ALL); l2tp_write_fields(provider, fd, OPT_L2); l2tp_write_option(fd, "pppoptfile =", pppd_name); return 0; }
static int write_pppd_option(struct vpn_provider *provider, int fd) { int i; const char *opt_s; l2tp_write_option(fd, "nodetach", NULL); l2tp_write_option(fd, "lock", NULL); l2tp_write_option(fd, "usepeerdns", NULL); l2tp_write_option(fd, "noipdefault", NULL); l2tp_write_option(fd, "noauth", NULL); l2tp_write_option(fd, "nodefaultroute", NULL); l2tp_write_option(fd, "ipparam", "l2tp_plugin"); for (i = 0; i < (int)ARRAY_SIZE(pppd_options); i++) { if (pppd_options[i].sub != OPT_ALL && pppd_options[i].sub != OPT_PPPD) continue; opt_s = vpn_provider_get_string(provider, pppd_options[i].cm_opt); if (!opt_s) opt_s = pppd_options[i].vpn_default; if (!opt_s) continue; if (pppd_options[i].type == OPT_STRING) l2tp_write_option(fd, pppd_options[i].pppd_opt, opt_s); else if (pppd_options[i].type == OPT_BOOL) l2tp_write_bool_option(fd, pppd_options[i].pppd_opt, opt_s); } l2tp_write_option(fd, "plugin", SCRIPTDIR "/libppp-plugin.so"); return 0; }
static int vc_save(struct vpn_provider *provider, GKeyFile *keyfile) { const char *option; int i; for (i = 0; i < (int)ARRAY_SIZE(vpnc_options); i++) { if (strncmp(vpnc_options[i].cm_opt, "VPNC.", 5) == 0) { if (!vpnc_options[i].cm_save) continue; option = vpn_provider_get_string(provider, vpnc_options[i].cm_opt); if (!option) continue; g_key_file_set_string(keyfile, vpn_provider_get_save_group(provider), vpnc_options[i].cm_opt, option); } } return 0; }
static int task_append_config_data(struct vpn_provider *provider, struct connman_task *task) { const char *option; int i; for (i = 0; i < (int)ARRAY_SIZE(oc_options); i++) { if (oc_options[i].oc_opt == NULL) continue; option = vpn_provider_get_string(provider, oc_options[i].cm_opt); if (option == NULL) continue; if (connman_task_add_argument(task, oc_options[i].oc_opt, oc_options[i].has_value ? option : NULL) < 0) return -EIO; } return 0; }
static int run_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name, vpn_provider_connect_cb_t cb, void *user_data, const char *username, const char *password) { const char *opt_s, *host; char *str; int err, i; host = vpn_provider_get_string(provider, "Host"); if (host == NULL) { connman_error("Host not set; cannot enable VPN"); err = -EINVAL; goto done; } if (username == NULL || password == NULL) { DBG("Cannot connect username %s password %p", username, password); err = -EINVAL; goto done; } vpn_provider_set_string(provider, "PPTP.User", username); vpn_provider_set_string(provider, "PPTP.Password", password); DBG("username %s password %p", username, password); str = g_strdup_printf("%s %s --nolaunchpppd --loglevel 2", PPTP, host); if (str == NULL) { connman_error("can not allocate memory"); err = -ENOMEM; goto done; } connman_task_add_argument(task, "pty", str); g_free(str); connman_task_add_argument(task, "nodetach", NULL); connman_task_add_argument(task, "lock", NULL); connman_task_add_argument(task, "usepeerdns", NULL); connman_task_add_argument(task, "noipdefault", NULL); connman_task_add_argument(task, "noauth", NULL); connman_task_add_argument(task, "nodefaultroute", NULL); connman_task_add_argument(task, "ipparam", "pptp_plugin"); for (i = 0; i < (int)ARRAY_SIZE(pptp_options); i++) { opt_s = vpn_provider_get_string(provider, pptp_options[i].cm_opt); if (opt_s == NULL) opt_s = pptp_options[i].vpnc_default; if (opt_s == NULL) continue; if (pptp_options[i].type == OPT_STRING) connman_task_add_argument(task, pptp_options[i].pptp_opt, opt_s); else if (pptp_options[i].type == OPT_BOOL) pptp_write_bool_option(task, pptp_options[i].pptp_opt, opt_s); } connman_task_add_argument(task, "plugin", SCRIPTDIR "/libppp-plugin.so"); err = connman_task_run(task, vpn_died, provider, NULL, NULL, NULL); if (err < 0) { connman_error("pptp failed to start"); err = -EIO; goto done; } done: if (cb != NULL) cb(provider, user_data, err); return err; }
static int ov_connect(struct vpn_provider *provider, struct connman_task *task, const char *if_name) { const char *option; int err, fd; option = vpn_provider_get_string(provider, "Host"); if (option == NULL) { connman_error("Host not set; cannot enable VPN"); return -EINVAL; } task_append_config_data(provider, task); option = vpn_provider_get_string(provider, "OpenVPN.ConfigFile"); if (option == NULL) { /* * Set some default options if user has no config file. */ option = vpn_provider_get_string(provider, "OpenVPN.TLSAuth"); if (option != NULL) { connman_task_add_argument(task, "--tls-auth", option); option = vpn_provider_get_string(provider, "OpenVPN.TLSAuthDir"); if (option != NULL) connman_task_add_argument(task, option, NULL); } connman_task_add_argument(task, "--nobind", NULL); connman_task_add_argument(task, "--persist-key", NULL); connman_task_add_argument(task, "--client", NULL); } connman_task_add_argument(task, "--syslog", NULL); connman_task_add_argument(task, "--script-security", "2"); connman_task_add_argument(task, "--up", SCRIPTDIR "/openvpn-script"); connman_task_add_argument(task, "--up-restart", NULL); connman_task_add_argument(task, "--setenv", NULL); connman_task_add_argument(task, "CONNMAN_BUSNAME", dbus_bus_get_unique_name(connection)); connman_task_add_argument(task, "--setenv", NULL); connman_task_add_argument(task, "CONNMAN_INTERFACE", CONNMAN_TASK_INTERFACE); connman_task_add_argument(task, "--setenv", NULL); connman_task_add_argument(task, "CONNMAN_PATH", connman_task_get_path(task)); connman_task_add_argument(task, "--dev", if_name); connman_task_add_argument(task, "--dev-type", "tun"); connman_task_add_argument(task, "--persist-tun", NULL); connman_task_add_argument(task, "--route-noexec", NULL); connman_task_add_argument(task, "--ifconfig-noexec", NULL); /* * Disable client restarts because we can't handle this at the * moment. The problem is that when OpenVPN decides to switch * from CONNECTED state to RECONNECTING and then to RESOLVE, * it is not possible to do a DNS lookup. The DNS server is * not accessable through the tunnel anymore and so we end up * trying to resolve the OpenVPN servers address. */ connman_task_add_argument(task, "--ping-restart", "0"); fd = fileno(stderr); err = connman_task_run(task, vpn_died, provider, NULL, &fd, &fd); if (err < 0) { connman_error("openvpn failed to start"); return -EIO; } return 0; }
static int request_cookie_input(struct vpn_provider *provider, struct oc_private_data *data) { DBusMessage *message; const char *path, *agent_sender, *agent_path; DBusMessageIter iter; DBusMessageIter dict; const char *str; int err; connman_agent_get_info(&agent_sender, &agent_path); if (provider == NULL || agent_path == NULL) return -ESRCH; message = dbus_message_new_method_call(agent_sender, agent_path, VPN_AGENT_INTERFACE, "RequestInput"); if (message == NULL) return -ENOMEM; dbus_message_iter_init_append(message, &iter); path = vpn_provider_get_path(provider); dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path); connman_dbus_dict_open(&iter, &dict); str = vpn_provider_get_string(provider, "OpenConnect.CACert"); if (str != NULL) connman_dbus_dict_append_dict(&dict, "OpenConnect.CACert", request_input_append_informational, (void *)str); str = vpn_provider_get_string(provider, "OpenConnect.ClientCert"); if (str != NULL) connman_dbus_dict_append_dict(&dict, "OpenConnect.ClientCert", request_input_append_informational, (void *)str); connman_dbus_dict_append_dict(&dict, "OpenConnect.ServerCert", request_input_append_mandatory, NULL); connman_dbus_dict_append_dict(&dict, "OpenConnect.VPNHost", request_input_append_mandatory, NULL); connman_dbus_dict_append_dict(&dict, "OpenConnect.Cookie", request_input_append_mandatory, NULL); vpn_agent_append_host_and_name(&dict, provider); connman_dbus_dict_close(&iter, &dict); err = connman_agent_queue_message(provider, message, connman_timeout_input_request(), request_input_cookie_reply, data); if (err < 0 && err != -EBUSY) { DBG("error %d sending agent request", err); dbus_message_unref(message); return err; } dbus_message_unref(message); return -EINPROGRESS; }
static int oc_notify(DBusMessage *msg, struct vpn_provider *provider) { DBusMessageIter iter, dict; const char *reason, *key, *value; 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); dbus_message_iter_get_basic(&iter, &reason); dbus_message_iter_next(&iter); if (!provider) { connman_error("No provider found"); return VPN_STATE_FAILURE; } if (strcmp(reason, "connect")) return VPN_STATE_DISCONNECT; domain = g_strdup(vpn_provider_get_string(provider, "VPN.Domain")); dbus_message_iter_recurse(&iter, &dict); while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry; dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_get_basic(&entry, &value); if (strcmp(key, "CISCO_CSTP_OPTIONS")) DBG("%s = %s", key, value); if (!strcmp(key, "VPNGATEWAY")) gateway = g_strdup(value); if (!strcmp(key, "INTERNAL_IP4_ADDRESS")) addressv4 = g_strdup(value); if (!strcmp(key, "INTERNAL_IP6_ADDRESS")) { addressv6 = g_strdup(value); prefix_len = 128; } if (!strcmp(key, "INTERNAL_IP4_NETMASK")) 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; 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")) vpn_provider_set_nameservers(provider, value); if (!strcmp(key, "CISCO_PROXY_PAC")) vpn_provider_set_pac(provider, value); if (domain == NULL && !strcmp(key, "CISCO_DEF_DOMAIN")) { g_free(domain); domain = g_strdup(value); } if (g_str_has_prefix(key, "CISCO_SPLIT_INC") == TRUE || g_str_has_prefix(key, "CISCO_IPV6_SPLIT_INC") == TRUE) vpn_provider_append_route(provider, key, value); dbus_message_iter_next(&dict); } 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); g_free(domain); 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); vpn_provider_set_ipaddress(provider, ipaddress); vpn_provider_set_domain(provider, domain); g_free(addressv4); g_free(addressv6); g_free(netmask); g_free(gateway); g_free(domain); connman_ipaddress_free(ipaddress); return VPN_STATE_CONNECT; }
static int l2tp_notify(DBusMessage *msg, struct vpn_provider *provider) { DBusMessageIter iter, dict; const char *reason, *key, *value; char *addressv4 = NULL, *netmask = NULL, *gateway = NULL; char *ifname = NULL, *nameservers = NULL; struct connman_ipaddress *ipaddress = NULL; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &reason); dbus_message_iter_next(&iter); if (!provider) { connman_error("No provider found"); return VPN_STATE_FAILURE; } if (strcmp(reason, "auth failed") == 0) { DBG("authentication failure"); vpn_provider_set_string(provider, "L2TP.User", NULL); vpn_provider_set_string(provider, "L2TP.Password", NULL); return VPN_STATE_AUTH_FAILURE; } if (strcmp(reason, "connect")) return VPN_STATE_DISCONNECT; dbus_message_iter_recurse(&iter, &dict); while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry; dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_get_basic(&entry, &value); DBG("%s = %s", key, value); if (!strcmp(key, "INTERNAL_IP4_ADDRESS")) addressv4 = g_strdup(value); if (!strcmp(key, "INTERNAL_IP4_NETMASK")) netmask = g_strdup(value); if (!strcmp(key, "INTERNAL_IP4_DNS")) nameservers = g_strdup(value); if (!strcmp(key, "INTERNAL_IFNAME")) ifname = g_strdup(value); dbus_message_iter_next(&dict); } if (vpn_set_ifname(provider, ifname) < 0) { g_free(ifname); g_free(addressv4); g_free(netmask); g_free(nameservers); return VPN_STATE_FAILURE; } if (addressv4) ipaddress = connman_ipaddress_alloc(AF_INET); g_free(ifname); if (!ipaddress) { connman_error("No IP address for provider"); g_free(addressv4); g_free(netmask); g_free(nameservers); return VPN_STATE_FAILURE; } value = vpn_provider_get_string(provider, "HostIP"); if (value) { vpn_provider_set_string(provider, "Gateway", value); gateway = g_strdup(value); } if (addressv4) connman_ipaddress_set_ipv4(ipaddress, addressv4, netmask, gateway); vpn_provider_set_ipaddress(provider, ipaddress); vpn_provider_set_nameservers(provider, nameservers); g_free(addressv4); g_free(netmask); g_free(gateway); g_free(nameservers); connman_ipaddress_free(ipaddress); return VPN_STATE_CONNECT; }