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;
}
Exemple #2
0
static int ov_connect(struct connman_provider *provider,
		struct connman_task *task, const char *if_name)
{
	const char *option;
	int err, fd;

	option = connman_provider_get_string(provider, "Host");
	if (option == NULL) {
		connman_error("Host not set; cannot enable VPN");
		return -EINVAL;
	}

	task_append_config_data(provider, task);

	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, "--tls-client", NULL);
	connman_task_add_argument(task, "--nobind", NULL);
	connman_task_add_argument(task, "--persist-key", NULL);
	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");

	connman_task_add_argument(task, "--client", NULL);

	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;
}