Technical info on oVirt agent and SSO

Since new KVM-VDI release it is possible to pass user and password from thin client to OS login, this eliminates need to enter user credentials second time to at OS side.

I’ve adopted oVirt solution for this. And since oVirt developers provide no documentation on its agent protocol, I’ve decided to make small whitepaper for myself ant anyone, who will bump into the same problem.

So, the idea of passing data to guest OS is rather simple:

Each guest OS must have ovirt-agent installed. oVirt agent is a python based server, which reads and writes to dedicated spice channel, thus allowing to pass data from and to hypervisor.

If we add the following config to VM device section:

<channel type='unix'>
 <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/VDI_win3203.com.kvm-vdi.0'/>
 <target type='virtio' name='com.kvm-vdi.0'/>
 <address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>

 

Freshly started VM will have a pass-through socket on hypervisor side

/var/lib/libvirt/qemu/channel/target/domain-N-machinename/com.kvm-vdi.o

and namedpipe/serial device on Windows/Linux guest os side (N=successful “virsh start”+1):

On Windows it will be represented as \\\\.\\Global\\com.kvm-vdi.0 named pipe.

On Linux it will represented as /dev/virtio-ports/com.kvm-vdi.0 serial device.

If oVirt agent is started successfully, we can connect to it and read statistical information:

socat /var/lib/libvirt/qemu/channel/target/domain-82-gnome1/com.kvm-vdi.0 -
{"__name__": "network-interfaces", "interfaces": [{"inet6": ["fe80::5054:ff:fe13:c86b"], "hw": "52:54:00:13:c8:6b", "inet": ["192.168.0.244"], "name": "eth0"}]}
{"__name__": "active-user", "name": "(unknown)"}
{"applications": ["ovirt-guest-agent-1.0.10.3-1.1", "xserver-xorg-video-qxl-0.1.1-2+b1"], "__name__": "applications"}

 

Okay, this is a simple part.

Now let’s see, how logins on each of guest OSes are implemented:

Windows uses a OVirtCredProv.dll with Credential Provider API. Since this DLL is ran as userid 0 it has no network connections and the only way to communicate with it are named pipes. So it creates \\\\.\\pipe\\VDSMDPipe.

Now when oVirt agent gets user credentials via Spice serial interface, it writes it to VDSMDPipe. OVirtCredProv.dll then completes login process.

You can pass user credentials from hypervisor side by writing Json formatted string to Spice socket:

echo "{\"__name__\": \"login\", \"username\": \"someuser\", \"password\": \"somepassword\"}" | socat /var/lib/libvirt/qemu/channel/target/domain-N-machineame/com.kvm-vdi.0 -

As for Linux it is somewhat similar. oVirt sugests using GDM manager for SSO. So remote logins happens in following sequence: Json-formatted user credentials are written to a Spice socket (see example above). oVirt agent sends dbus message to GDM stating, that login was successful also it sends a randomly generated number – a “token”, also creates a hidden socket at /tmp/ovirt-cred-channel. It reads this socket for 5 seconds. Meanwhile, after receiving data via DBUS, GDM initiates login with a help of  pam_ovirt_cred.so PAM module. Module writes token to  /tmp/ovirt-cred-channel. oVirt uses SO_PASSCRED flags on socket to get credentials (uid,gid,pid) of user, who writes to that channel. It then checks if specific uid is allowed to make logins.  If uid and token is accepted, oVirt then writes user login data to /tmp/ovirt-cred-channel, which are then used by pam to login. This completes Linux login sequence.

Tags :

About the Author

4 thoughts on “Technical info on oVirt agent and SSO

Leave a Reply to How to install oVirt guest agent on Debian OS and enable SSO Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.