Add DBUS communication in dbus.py, update README and add changes to sources
This commit is contained in:
		
							parent
							
								
									d606210675
								
							
						
					
					
						commit
						fb4cfa2413
					
				
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							@ -14,4 +14,20 @@
 | 
			
		||||
The following section briefly describes how to start the stuff for testing purposes
 | 
			
		||||
 | 
			
		||||
* `./src/nm-openvpn-service --bus-name org.freedesktop.NetworkManager.wireguard` to start the plugin
 | 
			
		||||
* `examples/dbus/dbus.py` to send Disconnect() to the plugin
 | 
			
		||||
* `examples/dbus/dbus.py` to send Disconnect() to the plugin
 | 
			
		||||
 | 
			
		||||
## Files
 | 
			
		||||
The following is a list of files that I created over the course of the project and is mainly for myself to keep track of them.
 | 
			
		||||
 | 
			
		||||
* `nm-wireguard-service.conf`
 | 
			
		||||
* `includes2strings.py`
 | 
			
		||||
 | 
			
		||||
## Knowledge
 | 
			
		||||
* The wireguard plugin basically handles incoming DBUS requests for the *NM VPN Plugin Interface* (can be looked at via `examples/dbus/dbus.py`)
 | 
			
		||||
* `auth-dialog/nm-openvpn-auth-dialog` reads the secrets from STDIN until the string "DONE" occurs and then proceeds to handle them
 | 
			
		||||
 | 
			
		||||
NM VPN Plugin:
 | 
			
		||||
https://developer.gnome.org/libnm-glib/stable/libnm-glib-NMVPNPlugin.html
 | 
			
		||||
 | 
			
		||||
Settings VPN (sent via DBus on Connect(a{sa{sv}}) method):
 | 
			
		||||
https://developer.gnome.org/libnm/stable/NMSettingVpn.html#nm-setting-vpn-get-data-item
 | 
			
		||||
@ -457,6 +457,8 @@ main (int argc, char *argv[])
 | 
			
		||||
	AskUserFunc ask_user_func = NULL;
 | 
			
		||||
	FinishFunc finish_func = NULL;
 | 
			
		||||
 | 
			
		||||
	// this describes how the arguments are supposed to be parsed
 | 
			
		||||
	// e.g. "-u UUID"
 | 
			
		||||
	GOptionContext *context;
 | 
			
		||||
	GOptionEntry entries[] = {
 | 
			
		||||
			{ "reprompt", 'r', 0, G_OPTION_ARG_NONE, &retry, "Reprompt for passwords", NULL},
 | 
			
		||||
@ -485,16 +487,22 @@ main (int argc, char *argv[])
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// the parameters are supplied via arguments
 | 
			
		||||
	printf("UUID: %s, Name: %s, Service: %s\n", vpn_uuid, vpn_name, vpn_service);
 | 
			
		||||
 | 
			
		||||
	if (strcmp (vpn_service, NM_VPN_SERVICE_TYPE_OPENVPN) != 0) {
 | 
			
		||||
		fprintf (stderr, "This dialog only works with the '%s' service\n", NM_VPN_SERVICE_TYPE_OPENVPN);
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf("Reading stdin details\n");
 | 
			
		||||
	// reads secrets/data from STDIN until "DONE" is read
 | 
			
		||||
	if (!nm_vpn_service_plugin_read_vpn_details (0, &data, &secrets)) {
 | 
			
		||||
		fprintf (stderr, "Failed to read '%s' (%s) data and secrets from stdin.\n",
 | 
			
		||||
		         vpn_name, vpn_uuid);
 | 
			
		||||
		return 1;
 | 
			
		||||
		//return 1; // TODO re-add
 | 
			
		||||
	}
 | 
			
		||||
	printf("Done reading\n");
 | 
			
		||||
 | 
			
		||||
	if (external_ui_mode) {
 | 
			
		||||
		no_secrets_required_func = eui_no_secrets_required;
 | 
			
		||||
 | 
			
		||||
@ -24,12 +24,14 @@ show_introspect = True
 | 
			
		||||
 | 
			
		||||
def send_desktop_notification(title="Hello World", msg="pydbus works!"):
 | 
			
		||||
    """Send a notification to the desktop environment to display"""
 | 
			
		||||
 | 
			
		||||
    bus = SessionBus()
 | 
			
		||||
    notifications = bus.get('.Notifications')
 | 
			
		||||
    notifications.Notify('test', 0, 'dialog-information', title, msg, [], {}, 5000)
 | 
			
		||||
 | 
			
		||||
def list_systemd_units():
 | 
			
		||||
    """Fetch all systemd units and print them"""
 | 
			
		||||
 | 
			
		||||
    bus = SystemBus()
 | 
			
		||||
 | 
			
		||||
    # systemd is now a proxy for the .systemd1 remote object
 | 
			
		||||
@ -42,6 +44,7 @@ def list_systemd_units():
 | 
			
		||||
 | 
			
		||||
def stop_start_systemd_unit(name="ssh.service"):
 | 
			
		||||
    """Stop and restart a systemd unit"""
 | 
			
		||||
 | 
			
		||||
    bus = SystemBus()
 | 
			
		||||
 | 
			
		||||
    # systemd is now a proxy for the .systemd1 remote object
 | 
			
		||||
@ -51,6 +54,7 @@ def stop_start_systemd_unit(name="ssh.service"):
 | 
			
		||||
 | 
			
		||||
def watch_for_new_systemd_jobs():
 | 
			
		||||
    """Wait for new systemd units and when they are created, print them out"""
 | 
			
		||||
 | 
			
		||||
    bus = SystemBus()
 | 
			
		||||
 | 
			
		||||
    # systemd is now a proxy for the .systemd1 remote object
 | 
			
		||||
@ -76,8 +80,9 @@ def hibernate():
 | 
			
		||||
        else:
 | 
			
		||||
            print("Cannot hibernate")
 | 
			
		||||
 | 
			
		||||
    except GLib.Error as e:
 | 
			
		||||
    except Exception as ex:
 | 
			
		||||
        print("Could not get PowerManager from DBUS")
 | 
			
		||||
        print(str(ex))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_wg_plugin(bus_name="org.freedesktop.NetworkManager.wireguard",
 | 
			
		||||
@ -98,15 +103,39 @@ def get_wg_plugin(bus_name="org.freedesktop.NetworkManager.wireguard",
 | 
			
		||||
 | 
			
		||||
def wg_disconnect(wg_plugin):
 | 
			
		||||
    """Disconnect the WG VPN plugin"""
 | 
			
		||||
 | 
			
		||||
    wg_plugin.Disconnect()
 | 
			
		||||
 | 
			
		||||
def wg_connect(wg_plugin):
 | 
			
		||||
    """Send the Connect Command to the Wireguard Plugin"""
 | 
			
		||||
 | 
			
		||||
    # these are the settings that are expected by Connect(a{sa{sv}}) for a VPN plugin
 | 
			
		||||
    service_type = GLib.Variant("s", "service")
 | 
			
		||||
    user_name = GLib.Variant("s", "wireguard")
 | 
			
		||||
    persistent = GLib.Variant("b", False)
 | 
			
		||||
    data = GLib.Variant("a{ss}", {"maxi": "cool"})
 | 
			
		||||
    secrets = GLib.Variant("a{ss}", {"name": "maxi moser"})
 | 
			
		||||
    timeout = GLib.Variant("u", 1337)
 | 
			
		||||
 | 
			
		||||
    # The DBus type: a{sa{sv}}
 | 
			
		||||
    # is a Dictionary with...
 | 
			
		||||
    # Key: Type ("wireless", "wired", "vpn", ...) -- we want VPN
 | 
			
		||||
    # Value: Dictionary with Key: Setting Name, Value: Setting Value
 | 
			
		||||
    settings = {"vpn":
 | 
			
		||||
                    {"service-type": service_type,
 | 
			
		||||
                        "user-name": user_name,
 | 
			
		||||
                        "persistent": persistent,
 | 
			
		||||
                        "data": data,
 | 
			
		||||
                        "secrets": secrets,
 | 
			
		||||
                        "timeout": timeout}
 | 
			
		||||
                }
 | 
			
		||||
    wg_plugin.Connect(settings)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
show_introspect = False
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    # send_desktop_notification("Guten Tag", "pydbus funktioniert, mein Herr!")
 | 
			
		||||
    # list_systemd_units()
 | 
			
		||||
    # hibernate()
 | 
			
		||||
    try:
 | 
			
		||||
        wg = get_wg_plugin()
 | 
			
		||||
        
 | 
			
		||||
@ -114,7 +143,7 @@ if __name__ == "__main__":
 | 
			
		||||
            print(wg.Introspect())
 | 
			
		||||
            help(wg)
 | 
			
		||||
 | 
			
		||||
        wg_disconnect(wg)
 | 
			
		||||
        wg_connect(wg)
 | 
			
		||||
 | 
			
		||||
    except Exception as ex:
 | 
			
		||||
        print(str(ex))
 | 
			
		||||
        print(str(ex))
 | 
			
		||||
 | 
			
		||||
@ -236,6 +236,28 @@ _LOGD_enabled (void)
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
wg_quick_find_exepath (void)
 | 
			
		||||
{
 | 
			
		||||
	static const char *paths[] = {
 | 
			
		||||
		"/usr/sbin/wg-quick",
 | 
			
		||||
		"/usr/bin/wg-quick",
 | 
			
		||||
		"/sbin/wg-quick",
 | 
			
		||||
		"/bin/wg-quick",
 | 
			
		||||
		"/usr/local/sbin/wg-quick",
 | 
			
		||||
		"/usr/local/bin/wg-quick",
 | 
			
		||||
	};
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < G_N_ELEMENTS(paths); i++) {
 | 
			
		||||
		if (g_file_test (paths[i], G_FILE_TEST_EXISTS)) {
 | 
			
		||||
			return paths[i];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
openvpn_binary_find_exepath (void)
 | 
			
		||||
{
 | 
			
		||||
@ -393,6 +415,59 @@ pids_pending_add (GPid pid, NMWireguardPlugin *plugin)
 | 
			
		||||
	gl.pids_pending_list = g_slist_prepend (gl.pids_pending_list, pid_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO implement me right
 | 
			
		||||
wg_quick_closed(GPid pid, gint status, gpointer user_data){
 | 
			
		||||
	PidsPendingData *pid_data = user_data;
 | 
			
		||||
	NMWireguardPlugin *plugin;
 | 
			
		||||
 | 
			
		||||
	if (WIFEXITED (status)) {
 | 
			
		||||
		int exit_status;
 | 
			
		||||
 | 
			
		||||
		exit_status = WEXITSTATUS (status);
 | 
			
		||||
		if (exit_status != 0)
 | 
			
		||||
			_LOGW ("wg-quick[%ld] exited with error code %d", (long) pid, exit_status);
 | 
			
		||||
		else
 | 
			
		||||
			_LOGI ("wg-quick[%ld] exited with success", (long) pid);
 | 
			
		||||
	}
 | 
			
		||||
	else if (WIFSTOPPED (status))
 | 
			
		||||
		_LOGW ("wg-quick[%ld] stopped unexpectedly with signal %d", (long) pid, WSTOPSIG (status));
 | 
			
		||||
	else if (WIFSIGNALED (status))
 | 
			
		||||
		_LOGW ("wg-quick[%ld] died with signal %d", (long) pid, WTERMSIG (status));
 | 
			
		||||
	else
 | 
			
		||||
		_LOGW ("wg-quick[%ld] died from an unnatural cause", (long) pid);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (pid_data);
 | 
			
		||||
	g_return_if_fail (pid_data->pid == pid);
 | 
			
		||||
	g_return_if_fail (g_slist_find (gl.pids_pending_list, pid_data));
 | 
			
		||||
 | 
			
		||||
	plugin = pid_data->plugin;
 | 
			
		||||
 | 
			
		||||
	pid_data->watch_id = 0;
 | 
			
		||||
	gl.pids_pending_list = g_slist_remove (gl.pids_pending_list , pid_data);
 | 
			
		||||
	pids_pending_data_free (pid_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO implement me right
 | 
			
		||||
static void
 | 
			
		||||
pids_pending_add_wg (GPid pid, NMWireguardPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
	PidsPendingData *pid_data;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (NM_IS_WIREGUARD_PLUGIN (plugin));
 | 
			
		||||
	g_return_if_fail (pid > 0);
 | 
			
		||||
 | 
			
		||||
	_LOGI ("wg-quick[%ld] started", (long) pid);
 | 
			
		||||
 | 
			
		||||
	pid_data = g_slice_new (PidsPendingData);
 | 
			
		||||
	pid_data->pid = pid;
 | 
			
		||||
	pid_data->kill_id = 0;
 | 
			
		||||
	pid_data->watch_id = g_child_watch_add (pid, wg_quick_closed, pid_data);
 | 
			
		||||
	pid_data->plugin = plugin;
 | 
			
		||||
	g_object_add_weak_pointer ((GObject *) plugin, (gpointer *) &pid_data->plugin);
 | 
			
		||||
 | 
			
		||||
	gl.pids_pending_list = g_slist_prepend (gl.pids_pending_list, pid_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
pids_pending_ensure_killed (gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
@ -2038,23 +2113,47 @@ real_disconnect (NMVpnServicePlugin *plugin,
 | 
			
		||||
static gboolean
 | 
			
		||||
test_connect (NMVpnServicePlugin *plugin,
 | 
			
		||||
				NMConnection *connection,
 | 
			
		||||
				GError **error)
 | 
			
		||||
				GError **err)
 | 
			
		||||
{
 | 
			
		||||
	_LOGI("Did a dummy connect");
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	printf("I Know It!\n");
 | 
			
		||||
	// FIXME find something useful
 | 
			
		||||
	char **cmd = {"touch", "/home/maxmanski/iknowhwatyoudidlastsummer", NULL};
 | 
			
		||||
	GPid pid = 0;
 | 
			
		||||
	GSpawnFlags spawn_flags = G_SPAWN_DO_NOT_REAP_CHILD;
 | 
			
		||||
	spawn_flags = G_SPAWN_DEFAULT;
 | 
			
		||||
	NMSettingVpn *setting = nm_connection_get_setting_vpn(connection);
 | 
			
		||||
	char *secret = nm_setting_vpn_get_secret(setting, "name");
 | 
			
		||||
	char *str_setting = nm_setting_to_string(setting);
 | 
			
		||||
	char *wg_quick_path = wg_quick_find_exepath();
 | 
			
		||||
	//char *
 | 
			
		||||
 | 
			
		||||
	if (!g_spawn_async (NULL, cmd, NULL, spawn_flags, NULL, NULL, &pid, error)){
 | 
			
		||||
	if(wg_quick_path == NULL){
 | 
			
		||||
		_LOGW("Error: Could not find wg-quick!");
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	printf("Setting to String: %s\n", str_setting);
 | 
			
		||||
	printf("Secret: %s\n", secret);
 | 
			
		||||
	
 | 
			
		||||
	//char **cmd = {wg_quick_path, "up", "mullvad", NULL};
 | 
			
		||||
	char **cmd = {"/usr/bin/touch", "/home/maxmanski/uwotm8", NULL};
 | 
			
		||||
	GPid pid = 0;
 | 
			
		||||
	GSpawnFlags spawn_flags = G_SPAWN_DO_NOT_REAP_CHILD;
 | 
			
		||||
	spawn_flags = G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_STDOUT_TO_DEV_NULL;
 | 
			
		||||
	spawn_flags = G_SPAWN_DEFAULT | G_SPAWN_DO_NOT_REAP_CHILD;
 | 
			
		||||
 | 
			
		||||
//	if (!g_spawn_async (NULL, cmd, NULL, spawn_flags, NULL, NULL, &pid, err)){
 | 
			
		||||
	int exit_code = 0;
 | 
			
		||||
	*err = NULL; // TODO remove?
 | 
			
		||||
 | 
			
		||||
	if (!g_spawn_async(NULL, cmd, NULL, spawn_flags, NULL, NULL, &pid, err)){
 | 
			
		||||
		_LOGW("An error occured while spawning wg-quick! (Error: %s)", (*err)->message);
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pids_pending_add_wg(pid, plugin);
 | 
			
		||||
	printf("PID of spawned command: %d\n", pid);
 | 
			
		||||
	// note: exit code 139 means SIGSEV (program died because of segfault or so)
 | 
			
		||||
	{ 
 | 
			
		||||
		printf("WG set up and ready to go!\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_LOGI("Did a dummy connect");
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user