Closed jkotra closed 2 years ago
Yes, this is expected. With v18_beta several signals are no longer broadcasted as it was before. Session specific signals now needs to be be "subscribed" to, where part of this process the request is going through a proper ACL check. In v17_beta and older, anyone could catch Log
and StatusChange
events. As of v18_beta, only users owning the session or granted access (via openvpn3 session-acl
) will receive these signals after requesting it.
You need to call the net.openvpn.v3.sessions.LogForward
method with the true
boolean to enable Log
and StatusChange
events, which is then tied to a specific session. This needs to be done for all sessions you want to receive log signals from.
What is being broadcasted still is the SessionManagerEvent
which gives just a very basic information that a session is created and started or disconnected and destroyed.
A very simple and naïve example, using the openvpn3
Python module:
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
import openvpn3
from openvpn3.constants import SessionManagerEventType
import time
# Set up GLib/D-Bus event loops and connect
mainloop = GLib.MainLoop()
dbusloop = DBusGMainLoop(set_as_default=True)
sysbus = dbus.SystemBus(mainloop=dbusloop)
# Callback functions for log events and status manager events
def log_event_cb(group, catg, msg):
print("{} {} {}".format(group, catg, msg))
def statusmgr_event_cb(event):
global session
print(str(event))
if event.GetType() == SessionManagerEventType.SESS_CREATED:
# Hack to allow the client backend to settle and initialize
time.sleep(1)
session = smgr.Retrieve(event.GetPath())
session.LogCallback(log_event_cb)
elif event.GetType() == SessionManagerEventType.SESS_DESTROYED:
session.LogCallback(None)
# Prepare Session Manager connection and activate callback functions
smgr = openvpn3.SessionManager(sysbus)
smgr.SessionManagerCallback(statusmgr_event_cb)
# Listen and handle events
mainloop.run()
Consider this a rough example, and if you want to capture log events from multiple VPN sessions - the global session
need to be done more clever to register all session objects in a container with a lookup. The time.sleep(1)
hack should also be avoided by rather having a loop with proper exception handling. But the advantage of the openvpn3
module is that it does all the proper LogForward
calls in the LogCallback()
setup method.
thanks @dsommers :+1: .
Nice implementation you have there in eOVPN, @jkotra! Wonderful to see the D-Bus API being used by other client front-ends.
I have one remark though. You should ideally use the openpvn3.constants
instead of hard-coding the various status codes. Those constants are not guaranteed to be stable between different versions, even though we try to avoid changing it without a good reason.
Looking deeper
net.openvpn.v3.sessions.Connect()
, you should first call net.openvpn.v3.sessions.Ready()
and check if it returns an error. This error indicates if all required credentials has been provided. Also note that ....Connect()
may fail as well, where a call to ....Ready()
will give more details. Failures here are typically related to configurations using --static-challenge
, which should be retrieved before connecting.net.openvpn.v3.sessions.AttentionRequired
signal as well as setting the session status accordingly after Connect()
has been called, where it requests more credentials.send_auth()
implementation is fragile. There is no guarantee that these user input fields will be requested in that order, nor that it will be asked for both values. And this implementation may fail if MFA tokens are required.return
if an error occurs when disconnecting all clients. If an error occurs here, you probably don't want to halt disconnecting other clientsset_log_forward()
is lacking a g_assert(UniqueSession != NULL);
check, which you use many other places.Thanks for the comprehensive code review 🤗
I will work on them this week.
Hard coded StatusMajor and StatusMinor values - also here; I will consider to package a development package which can be used when compiling external projects - which provides a header file with these values.
I got an Unconventional (?) Idea, how about exposing this enum as dbus method returning {us}
(kv pair/dict)?
To get these constants from python lib inside flatpak container, i had to do some tricks that are prone to failure in older distros.
Possible solutions:
distributing to pip / pypi. In case version installed on user system is different then pip, might cause problems. Developer has to maintain breakpoint list of enum changes by version and compare them.
flatpak extension. openvpn3 py is included in flatpak build. Same issues as above. Can't guarantee version sync b/w user and sandbox.
expose enum via DBus. Optimal solution in my opinion.
(willing/intrested to work on this feature)
Issue
I listen to
StatusChange
signal fromnet.openvpn.v3.sessions
and reply accordingly, sincev18
update, no events are being emitted most of the time. once in 10-20 tries,(2 4 Username/password credentials needed)
gets emitted but nothing other then/after that.Demo
v17-b3
works as expected.