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;
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
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;
}
Beispiel #8
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;
}
Beispiel #9
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);
}
Beispiel #12
0
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;
}
Beispiel #13
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;
}
Beispiel #14
0
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;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #18
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;
}
Beispiel #19
0
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;
}
Beispiel #22
0
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;
}