Пример #1
0
static void
get_property (GObject *object, guint prop_id,
              GValue *value, GParamSpec *pspec)
{
	NMSettingVpn *setting = NM_SETTING_VPN (object);
	NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);

	switch (prop_id) {
	case PROP_SERVICE_TYPE:
		g_value_set_string (value, nm_setting_vpn_get_service_type (setting));
		break;
	case PROP_USER_NAME:
		g_value_set_string (value, nm_setting_vpn_get_user_name (setting));
		break;
	case PROP_PERSISTENT:
		g_value_set_boolean (value, priv->persistent);
		break;
	case PROP_DATA:
		g_value_take_boxed (value, _nm_utils_copy_strdict (priv->data));
		break;
	case PROP_SECRETS:
		g_value_take_boxed (value, _nm_utils_copy_strdict (priv->secrets));
		break;
	case PROP_TIMEOUT:
		g_value_set_uint (value, nm_setting_vpn_get_timeout (setting));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
Пример #2
0
static void
get_property (GObject *object, guint prop_id,
		    GValue *value, GParamSpec *pspec)
{
	NMSettingVPN *setting = NM_SETTING_VPN (object);
	NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting);

	switch (prop_id) {
	case PROP_SERVICE_TYPE:
		g_value_set_string (value, nm_setting_vpn_get_service_type (setting));
		break;
	case PROP_USER_NAME:
		g_value_set_string (value, nm_setting_vpn_get_user_name (setting));
		break;
	case PROP_DATA:
		g_value_set_boxed (value, priv->data);
		break;
	case PROP_SECRETS:
		g_value_set_boxed (value, priv->secrets);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static gboolean
_service_cache_credentials (NML2tpPppService *self,
							NMConnection *connection,
							GError **error)
{
	NML2tpPppServicePrivate *priv = NM_L2TP_PPP_SERVICE_GET_PRIVATE (self);
	NMSettingVPN *s_vpn;
	const char *username, *password, *domain;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (connection != NULL, FALSE);

	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
	if (!s_vpn) {
		g_set_error_literal (error,
							 NM_VPN_PLUGIN_ERROR,
							 NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
		                     _("Could not find secrets (connection invalid, no vpn setting)."));
		return FALSE;
	}

	/* Username; try L2TP specific username first, then generic username */
	username = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_USER);
	if (username && strlen (username)) {
		/* FIXME: This check makes about 0 sense. */
		if (!username || !strlen (username)) {
			g_set_error_literal (error,
								 NM_VPN_PLUGIN_ERROR,
								 NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
			                     _("Invalid VPN username."));
			return FALSE;
		}
	} else {
		username = nm_setting_vpn_get_user_name (s_vpn);
		if (!username || !strlen (username)) {
			g_set_error_literal (error,
								 NM_VPN_PLUGIN_ERROR,
								 NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
								 _("Missing VPN username."));
			return FALSE;
		}
	}

	password = nm_setting_vpn_get_secret (s_vpn, NM_L2TP_KEY_PASSWORD);
	if (!password || !strlen (password)) {
		g_set_error_literal (error,
							 NM_VPN_PLUGIN_ERROR,
							 NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
							 _("Missing or invalid VPN password."));
		return FALSE;
	}

	domain = nm_setting_vpn_get_data_item (s_vpn, NM_L2TP_KEY_DOMAIN);
	if (domain && strlen (domain))
		priv->domain = g_strdup(domain);

	priv->username = g_strdup(username);
	priv->password = g_strdup(password);
	return TRUE;
}
static gboolean
handle_need_secrets (NMDBusSstpPpp *object,
                     GDBusMethodInvocation *invocation,
                     gpointer user_data)
{
	NMSstpPlugin *self = NM_SSTP_PLUGIN (user_data);
	NMSstpPluginPrivate *priv = NM_SSTP_PLUGIN_GET_PRIVATE (self);
	NMSettingVpn *s_vpn;
	const char *user, *password, *domain;
	gchar *username;

	remove_timeout_handler (NM_SSTP_PLUGIN (user_data));

	s_vpn = nm_connection_get_setting_vpn (priv->connection);
	g_assert (s_vpn);

	/* Username; try SSTP specific username first, then generic username */
	user = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_USER);
	if (!user || !strlen (user))
		user = nm_setting_vpn_get_user_name (s_vpn);
	if (!user || !strlen (user)) {
		g_dbus_method_invocation_return_error_literal (invocation,
		                                               NM_VPN_PLUGIN_ERROR,
		                                               NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
		                                               _("Missing VPN username."));
		return FALSE;
	}

	password = nm_setting_vpn_get_secret (s_vpn, NM_SSTP_KEY_PASSWORD);
	if (!password || !strlen (password)) {
		g_dbus_method_invocation_return_error_literal (invocation,
		                                               NM_VPN_PLUGIN_ERROR,
		                                               NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
		                                               _("Missing or invalid VPN password."));
		return FALSE;;
	}

	/* Domain is optional */
	domain = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_DOMAIN);

	/* Success */
	if (domain && strlen (domain))
		username = g_strdup_printf ("%s\\%s", domain, user);
	else
		username = g_strdup (user);

	nmdbus_sstp_ppp_complete_need_secrets (object, invocation, username, password);
	g_free (username);

	return TRUE;
}
static gboolean
real_connect (NMVPNPlugin   *plugin,
              NMConnection  *connection,
              GError       **error)
{
	NMSettingVPN *s_vpn;
	const char *user_name;

	s_vpn = NM_SETTING_VPN (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN));
	if (!s_vpn) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
		             "%s",
		             "Could not process the request because the VPN connection settings were invalid.");
		return FALSE;
	}

	user_name = nm_setting_vpn_get_user_name (s_vpn);
	if (!user_name && !nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_USER)) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_CONNECTION_INVALID,
					 "%s",
					 "Could not process the request because no username was provided.");
		return FALSE;
	}

	/* Validate the properties */
	if (!nm_openssh_properties_validate (s_vpn, error))
		return FALSE;

	/* Finally try to start sshtun */
	if (!nm_openssh_start (plugin, s_vpn, error))
		return FALSE;

	return TRUE;
}
static GPtrArray *
construct_pppd_args (NMSstpPlugin *plugin,
                     NMSettingVpn *s_vpn,
                     const char *pppd,
                     const char *gwaddr,
                     GError **error)
{
	GPtrArray *args = NULL;
	const char *value, *sstp_binary;
	char *ipparam, *tmp, *ca_cert = NULL, *proxy = NULL, *uuid = NULL;
	const char *proxy_server, *proxy_port;
	gboolean ign_cert;


	/* Get the proxy settings */
	proxy_server = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_PROXY_SERVER);
	proxy_port = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_PROXY_PORT);
	if (proxy_server && proxy_port && strlen(proxy_server) && strlen(proxy_port)) {
		const char *proxy_user, *proxy_password;
		long int tmp_int;

		if (!str_to_int (proxy_port, &tmp_int))
			tmp_int = 0;

		proxy_user = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_PROXY_USER);
		proxy_password = nm_setting_vpn_get_secret (s_vpn, NM_SSTP_KEY_PROXY_PASSWORD);

		proxy = g_strdup_printf("--proxy http://%s%s%s@%s:%ld",
		                        proxy_user,
		                        proxy_password ? ":" : "",
		                        proxy_password ?     : "",
		                        proxy_server,
		                        tmp_int);
	}

	sstp_binary = nm_find_sstpc ();
	if (!sstp_binary) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		             "%s",
		             _("Could not find sstp client binary."));
		return FALSE;
	}

	/* Validate the Gateway option */
	if (!gwaddr || !strlen (gwaddr)) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
		             "%s",
		             _("Missing VPN gateway."));
		goto error;
	}

	/* Create the argument vector for pppd */
	args = g_ptr_array_new ();
	g_ptr_array_add (args, (gpointer) g_strdup (pppd));
	g_ptr_array_add (args, (gpointer) g_strdup ("pty"));

	/* Get the CA Certificate (if any) */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_CA_CERT);
	if (value && strlen (value))
		ca_cert = g_strdup_printf ("--ca-cert %s", value);

    /*  Set the UUID of the connection */
    value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_UUID);
    if (value && strlen(value))
        uuid = g_strdup_printf ("--uuid %s", value);

	/* Ignore any certificate warnings */
	value = nm_setting_vpn_get_data_item(s_vpn, NM_SSTP_KEY_IGN_CERT_WARN);
	if (value && !strcmp(value, "yes")) {
		ign_cert = TRUE;
	}

	/* Prepare the PTY option */
	ipparam = g_strdup_printf ("nm-sstp-service-%d", getpid ());
	tmp = g_strdup_printf ("%s %s %s --nolaunchpppd %s %s --ipparam %s %s %s",
						   sstp_binary, gwaddr,
						   ign_cert == TRUE ? "--cert-warn" : "",
						   debug ? "--log-level 4" : "",
						   proxy ? proxy : "",
						   ipparam,
                           uuid ? uuid : "",
						   ca_cert ? ca_cert : ""
						   );

	g_ptr_array_add (args, (gpointer) tmp);
    if (ca_cert)
    	g_free(ca_cert);
    if (uuid)
        g_free(uuid);

	/* Enable debug */
	if (debug)
		g_ptr_array_add (args, (gpointer) g_strdup ("debug"));

	/* PPP options */
	g_ptr_array_add (args, (gpointer) g_strdup ("noipv6"));
	g_ptr_array_add (args, (gpointer) g_strdup ("ipparam"));
	g_ptr_array_add (args, (gpointer) ipparam);

	g_ptr_array_add (args, (gpointer) g_strdup ("nodetach"));
	g_ptr_array_add (args, (gpointer) g_strdup ("lock"));
	g_ptr_array_add (args, (gpointer) g_strdup ("usepeerdns"));
	g_ptr_array_add (args, (gpointer) g_strdup ("noipdefault"));
	g_ptr_array_add (args, (gpointer) g_strdup ("nodefaultroute"));

	/* Don't need to auth the SSTP server */
	g_ptr_array_add (args, (gpointer) g_strdup ("noauth"));

	/* Username; try SSTP specific username first, then generic username */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_USER);
	if (!value || !strlen (value))
		value = nm_setting_vpn_get_user_name (s_vpn);
	if (!value || !strlen (value)) {
		g_set_error_literal (error,
		                     NM_VPN_PLUGIN_ERROR,
		                     NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION,
		                     _("Missing VPN username."));
		return FALSE;
	}
	g_ptr_array_add (args, (gpointer) g_strdup ("user"));
	g_ptr_array_add (args, (gpointer) g_strdup (value));

	/* Allow EAP (currently not supported */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REFUSE_EAP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-eap"));

	/* Allow plain text passwords */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REFUSE_PAP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-pap"));

	/* Allow CHAP-MD5 */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REFUSE_CHAP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-chap"));

	/* Allow MSCHAP */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REFUSE_MSCHAP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-mschap"));

	/* Allow MSCHAP-v2 */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REFUSE_MSCHAPV2);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("refuse-mschap-v2"));

	/* Require MPPE */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REQUIRE_MPPE);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe"));

	/* Use MPPE-40 bit */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REQUIRE_MPPE_40);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe-40"));

	/* Use MPPE-128 bit */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_REQUIRE_MPPE_128);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("require-mppe-128"));

	/* Use stateful MPPE */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_MPPE_STATEFUL);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("mppe-stateful"));

	/* No BSD Compression */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_NOBSDCOMP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("nobsdcomp"));

	/* No Deflate */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_NODEFLATE);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("nodeflate"));

	/* No Compression */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_NO_VJ_COMP);
	if (value && !strcmp (value, "yes"))
		g_ptr_array_add (args, (gpointer) g_strdup ("novj"));

	/* LCP Echo Failure */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_LCP_ECHO_FAILURE);
	if (value && strlen (value)) {
		long int tmp_int;

		/* Convert to integer and then back to string for security's sake
		 * because strtol ignores some leading and trailing characters.
		 */
		if (str_to_int (value, &tmp_int)) {
			g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-failure"));
			g_ptr_array_add (args, (gpointer) g_strdup_printf ("%ld", tmp_int));
		} else {
			g_warning ("failed to convert lcp-echo-failure value '%s'", value);
		}
	} else {
		g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-failure"));
		g_ptr_array_add (args, (gpointer) g_strdup ("0"));
	}

	/* LCP Echo Interval */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_LCP_ECHO_INTERVAL);
	if (value && strlen (value)) {
		long int tmp_int;

		/* Convert to integer and then back to string for security's sake
		 * because strtol ignores some leading and trailing characters.
		 */
		if (str_to_int (value, &tmp_int)) {
			g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-interval"));
			g_ptr_array_add (args, (gpointer) g_strdup_printf ("%ld", tmp_int));
		} else {
			g_warning ("failed to convert lcp-echo-interval value '%s'", value);
		}
	} else {
		g_ptr_array_add (args, (gpointer) g_strdup ("lcp-echo-interval"));
		g_ptr_array_add (args, (gpointer) g_strdup ("0"));
	}

	/* Unit Number */
	value = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_UNIT_NUM);
	if (value && *value) {
		long int tmp_int;
		if (str_to_int (value, &tmp_int)) {
			g_ptr_array_add (args, (gpointer) g_strdup ("unit"));
			g_ptr_array_add (args, (gpointer) g_strdup_printf ("%ld", tmp_int));
		} else
			g_warning ("failed to convert unit value '%s'", value);
	}

	/* Add the SSTP PPP Plugin */
	g_ptr_array_add (args, (gpointer) g_strdup ("plugin"));
	g_ptr_array_add (args, (gpointer) g_strdup (NM_SSTP_PPPD_PLUGIN));

	/* Terminate pointer array with NULL */
	g_ptr_array_add (args, NULL);

	return args;

error:
	free_pppd_args (args);
	return FALSE;
}
static gboolean
nm_openssh_start (NMVPNPlugin *plugin, NMSettingVPN *s_vpn, GError **error)
{
	NMOpensshPluginPrivate *priv = NM_OPENSSH_PLUGIN_GET_PRIVATE(plugin);
	sshtun_handle_t handle;
	const char *tun_mode;
	char *tun_owner = NULL, *host = NULL, *user = NULL,
		*public_key = NULL, *private_key = NULL, *config_script = NULL;
	const char *val;
	int ret;
	gboolean retval = TRUE;
	GIOChannel *event_channel;
	GSource *child_watch, *event_watch;

	val = nm_setting_vpn_get_user_name (s_vpn);
	if (!val) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
					 "%s",
					 "Can't get username.");
		retval = FALSE;
		goto out;
	}
	tun_owner = g_strdup (val);

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_TUN_USE_TAP);
	tun_mode = val && !strcmp (val, "yes") ? "ethernet" : "pointopoint";

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_USER);
	user = val ? g_strdup (val) : g_strdup (tun_owner);

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_HOST);
	if (!val) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
					 "%s",
					 "Host is missing.");
		retval = FALSE;
		goto out;
	}
	host = g_strdup (val);

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_PUBLIC_KEY);
	if (!val) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
					 "%s",
					 "SSH public key is missing.");
		retval = FALSE;
		goto out;
	}
	public_key = g_strdup (val);

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_PRIVATE_KEY);
	if (!val) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
					 "%s",
					 "SSH private key is missing.");
		retval = FALSE;
		goto out;
	}
	private_key = g_strdup (val);

	val = nm_setting_vpn_get_data_item (s_vpn, NM_OPENSSH_KEY_CONFIG_SCRIPT);
	if (!val) {
		g_set_error (error,
					 NM_VPN_PLUGIN_ERROR,
					 NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
					 "%s",
					 "IP config script is missing.");
		retval = FALSE;
		goto out;
	}
	config_script = g_strdup (val);

	ret = sshtun_new (&handle);
	if (ret < 0) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_GENERAL,
		             "%s",
		             "Could not allocate memory for an sshtun process.");
		retval = FALSE;
		goto out;
	}

	ret = sshtun_set_params (handle,
							 SSHTUN_PARAM_TUN_MODE, tun_mode,
							 SSHTUN_PARAM_TUN_OWNER, tun_owner,
							 SSHTUN_PARAM_USER, user,
							 SSHTUN_PARAM_HOST, host,
							 SSHTUN_PARAM_SERVICE, "ssh",
							 SSHTUN_PARAM_PUBLIC_KEY, public_key,
							 SSHTUN_PARAM_PRIVATE_KEY, private_key,
							 SSHTUN_PARAM_CONFIG_SCRIPT, config_script,
							 0);
	if (ret < 0) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
		             "%s",
		             "Could not set parameters for an sshtun process.");
		retval = FALSE;
		goto out;
	}

	ret = sshtun_start (handle);
	if (ret < 0) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		             "%s",
		             "Could not start an sshtun process.");
		retval = FALSE;
		goto out;
	}

	priv->handle = handle;

	val = nm_setting_vpn_get_secret (s_vpn, NM_OPENSSH_KEY_PASSWORD);
	priv->password = val ? g_strdup (val) : NULL;

	/* Watch the status change of the sshtun child process. */
	child_watch = g_child_watch_source_new (sshtun_pid (priv->handle));
	g_source_set_callback (child_watch,
						   (GSourceFunc) child_watch_cb, plugin,
						   NULL);
	g_source_attach (child_watch, NULL);
	g_source_unref (child_watch);

	/* Watch the normal event from the sshtun child process. */
	event_channel =	g_io_channel_unix_new (sshtun_event_fd (priv->handle));
	event_watch = g_io_create_watch (event_channel, G_IO_IN);
	g_source_set_callback (event_watch,
						   (GSourceFunc) event_watch_cb, plugin,
						   NULL);
	g_source_attach (event_watch, NULL);
	g_source_unref (event_watch);
	g_io_channel_unref (event_channel);

 out:
	g_free (tun_owner);
	g_free (host);
	g_free (user);
	g_free (public_key);
	g_free (private_key);
	g_free (config_script);

	return retval;
}