static int l2tp_connect(struct connman_provider *provider, struct connman_task *task, const char *if_name) { const char *host; char *l2tp_name, *pppd_name; int l2tp_fd, pppd_fd; int err; if (connman_task_set_notify(task, "getsec", l2tp_get_sec, provider)) return -ENOMEM; host = connman_provider_get_string(provider, "Host"); if (host == NULL) { connman_error("Host not set; cannot enable VPN"); return -EINVAL; } l2tp_name = g_strdup_printf("/var/run/connman/connman-xl2tpd.conf"); l2tp_fd = open(l2tp_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); if (l2tp_fd < 0) { g_free(l2tp_name); connman_error("Error writing l2tp config"); return -EIO; } pppd_name = g_strdup_printf("/var/run/connman/connman-ppp-option.conf"); pppd_fd = open(pppd_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); if (pppd_fd < 0) { connman_error("Error writing pppd config"); g_free(l2tp_name); g_free(pppd_name); close(l2tp_fd); return -EIO; } l2tp_write_config(provider, pppd_name, l2tp_fd); write_pppd_option(provider, pppd_fd); connman_task_add_argument(task, "-D", NULL); connman_task_add_argument(task, "-c", l2tp_name); g_free(l2tp_name); g_free(pppd_name); err = connman_task_run(task, l2tp_died, provider, NULL, NULL, NULL); if (err < 0) { connman_error("l2tp failed to start"); return -EIO; } return 0; }
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 vpn_connect(struct connman_provider *provider) { struct vpn_data *data = connman_provider_get_data(provider); struct vpn_driver_data *vpn_driver_data; const char *name; int ret = 0; if (data != NULL) return -EISCONN; data = g_try_new0(struct vpn_data, 1); if (data == NULL) return -ENOMEM; data->provider = connman_provider_ref(provider); data->watch = 0; data->flags = 0; data->task = NULL; data->state = VPN_STATE_IDLE; connman_provider_set_data(provider, data); name = connman_provider_get_driver_name(provider); if (name == NULL) return -EINVAL; vpn_driver_data = g_hash_table_lookup(driver_hash, name); if (vpn_driver_data != NULL && vpn_driver_data->vpn_driver != NULL && vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) { ret = vpn_create_tun(provider); if (ret < 0) goto exist_err; } data->task = connman_task_create(vpn_driver_data->program); if (data->task == NULL) { ret = -ENOMEM; stop_vpn(provider); goto exist_err; } if (connman_task_set_notify(data->task, "notify", vpn_notify, provider)) { ret = -ENOMEM; stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } ret = vpn_driver_data->vpn_driver->connect(provider, data->task, data->if_name); if (ret < 0) { stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } DBG("%s started with dev %s", vpn_driver_data->provider_driver.name, data->if_name); data->state = VPN_STATE_CONNECT; return -EINPROGRESS; exist_err: connman_provider_set_index(provider, -1); connman_provider_set_data(provider, NULL); connman_provider_unref(data->provider); g_free(data->if_name); g_free(data); return ret; }
static int vpn_connect(struct vpn_provider *provider, vpn_provider_connect_cb_t cb, const char *dbus_sender, void *user_data) { struct vpn_data *data = vpn_provider_get_data(provider); struct vpn_driver_data *vpn_driver_data; const char *name; int ret = 0; enum vpn_state state = VPN_STATE_UNKNOWN; if (data) state = data->state; DBG("data %p state %d", data, state); switch (state) { case VPN_STATE_UNKNOWN: data = g_try_new0(struct vpn_data, 1); if (!data) return -ENOMEM; data->provider = vpn_provider_ref(provider); data->watch = 0; data->flags = 0; data->task = NULL; vpn_provider_set_data(provider, data); /* fall through */ case VPN_STATE_DISCONNECT: case VPN_STATE_IDLE: case VPN_STATE_FAILURE: case VPN_STATE_AUTH_FAILURE: data->state = VPN_STATE_IDLE; break; case VPN_STATE_CONNECT: return -EINPROGRESS; case VPN_STATE_READY: return -EISCONN; } name = vpn_provider_get_driver_name(provider); if (!name) return -EINVAL; vpn_driver_data = g_hash_table_lookup(driver_hash, name); if (!vpn_driver_data || !vpn_driver_data->vpn_driver) { ret = -EINVAL; goto exist_err; } if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) { ret = vpn_create_tun(provider); if (ret < 0) goto exist_err; } data->task = connman_task_create(vpn_driver_data->program); if (!data->task) { ret = -ENOMEM; stop_vpn(provider); goto exist_err; } if (connman_task_set_notify(data->task, "notify", vpn_notify, provider)) { ret = -ENOMEM; stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } ret = vpn_driver_data->vpn_driver->connect(provider, data->task, data->if_name, cb, dbus_sender, user_data); if (ret < 0 && ret != -EINPROGRESS) { stop_vpn(provider); connman_task_destroy(data->task); data->task = NULL; goto exist_err; } DBG("%s started with dev %s", vpn_driver_data->provider_driver.name, data->if_name); data->state = VPN_STATE_CONNECT; return -EINPROGRESS; exist_err: vpn_provider_set_index(provider, -1); vpn_provider_set_data(provider, NULL); vpn_provider_unref(data->provider); g_free(data->if_name); g_free(data); return ret; }