Category Archives: planetkde

A KDecoration2 update

Before heading into the weekend I thought about writing a small update about the KDecoration2 status. Since my last blog post I started integrating KDecoration2 into KWin. This was partially easier and partially more difficult than anticipated. Especially ripping out the old decoration code is rather complex. There are quite some design differences which make the transition complex and especially values inside KWin core are using enums defined in the decoration API – e.g. the maximized state is kept as a KDecorationDefines::MaximizedMode. This will need further work to move the enums and so at the moment the old decoration library is still compiled although the library is no longer in use.

Ah that means there is code? Yes, today I pushed the branch as “graesslin/kdecoration2″ into kde:kwin git repository. To give it a proper try you also need the kde:kdecoration (master branch) and kde:breeze also on “graesslin/kdecoration2″ branch. The new decoration API is working quite well and I’m rather satisfied. The memory usage of KWin dropped significantly. In a previous report I mentioned that KWin needs around 200 MB, right now my KWin only needs around 40 MB, the number of open windows is a little bit smaller, but still it shows in the right direction. And that’s without any optimisations. There is still some optimization potential in Breeze (check out our todos, all purple tasks are in Breeze) and in KWin (red tasks). Also a nice improvement is that the window decoration no longer flickers when resizing the window. This is a rather big annoyance of KWin 5.0. I expected that the new API would fix this issue, but seeing it confirmed is really nice :-)

Last but not least the restart of KWin got faster which is a nice improvement for KWin developers, for users it’s not that important. The reason for this is that when we enabled/disabled compositing we recreated the window decorations. So when restarting KWin we first created all windows with their decoration before enabling compositing to just destroy them and create them again (yes it would have been possible to improve it, but it doesn’t hit users). Now with the new API there is no need to recreate the decoration. Only a Renderer is exchanged, but the rendering is delayed till it’s needed.

This screen shot does not only show the new Breeze decoration, but also some new features: when quick tiling a window the borders cornering the screen edges are removed. Also in the preview application one can see that the decoration scales which is nice for high-dpi screens. The decoration API follows the approach Plasma is using.

I have been running a KWin with the new decoration API since Monday, which means we are close to start the review process. But there’s of course still work to be done and I’d appreciate any help. The window tab API is not yet implemented, the configuration module needs adjustments to load and render the new deco and most important we have to port the existing decorations like Oxygen, Aurorae, deKorator and QtCurve. For the last three I want to improve the theme experience by allowing the plugin to say that it supports themes directly in the JSON meta data and point to where to find them. So the configuration module can just show all of them. The trick will be to pass the to be used theme to the factory method (we have a nice QVariantList there which can be used). Also the meta data will make it possible to point to GHNS configuration files so that we can not only download Aurorae themes from the configuration module, but also other themes.

KDecoration2 – The road ahead

Yesterday I blogged about why Breeze is not the default window decoration in KWin 5.0. The blog post touched a little bit the problems with our decoration API. In short: it’s QWidget based and that doesn’t fit our needs any more. It uses a QWidget as an X11 window. At the same time KWin intercepts the rendering and also input handling, redirects it and forwards it. So why use a QWidget at all? Also using a QWidget is quite a memory waste in the Qt5 world. The QWindow behind the QWidget uses a QXcbShmImage with the same size as the window. As explained in yesterdays blog post the window has the size of the managed window plus the decoration. So for a maximized window we hold an image of the size of the complete window while we just need the titlebar strip. We can do better :-)

Our decoration API is also showing it’s age. It’s cumbersome to use, too difficult to use. In fact there is a KDecoration and a KCommonDecoration – the latter trying to make KDecoration easier to use by for example providing buttons. The API got extended several times to support more features which are all optional. The API is difficult to use from KWin side as it’s not stateful and quite often needs to call into the decoration API calling virtual methods the decoration API provider needs to implement. Last but not least it’s difficult to test new decorations as we don’t have a dedicated viewer application to test the interaction and painting. You have to kind of use KWin as the development host. Not the best solution.

The idea for a new API had been in the room for a long time. I opened a bug report for it more than two years ago. Last week I finally started with the implementation and tackled three things at the same time:

  • New decoration API
  • Viewer application
  • Breeze decoration

In the current state it looks like this:

The outer decoration is the existing Aurorae theme. It looks already quite good, but there is of course still lots of work to do. The API is not yet feature complete, it needs implementation in KWin and Breeze needs a pixel perfectionist to get it right (which I am not). And that’s where you can help! Thanks to our sysadmins we have a new todo board and I requested a project for KDecoration2 and prefilled it with very easy tasks. This is a wonderful opportunity to work on easy and new code and helping both KWin and the Visual Design Group achieving an important new step. Without your help we won’t have this in 5.1 and it would be so important for both KWin and the overall design of the Plasma desktop. So please grab the code and start hacking. Grabbing the code, where? The new decoration API can be found in the git repository kde:kdecoration, the viewer application in git repository kde:kdecoration-viewer and the new Breeze window decoration in git repository kde:breeze in branch “graesslin/kdecoration2″.

So what makes KDecoration2 better? Obviously it’s no longer QWidget or QWindow based. Instead it’s a pure QObject based API. It provides a paint method a plugin needs to implement which gets a QPainter passed into. This allows KWin to control the rendering and to render to the best suited backend for the current compositor (e.g. just a QImage or a Shm shared pixmap). Also the input handling will be controlled from the backend side by sending appropriate events to the decoration. The API takes care of all of the handling – activating the buttons forwarding title bar presses, etc. This alone makes the API hopefully much easier to use from plugin side. It also provides the base implementation for all the required buttons, so that the decoration only needs to provide the painting of the buttons. Simplified the API looks like the following:

There’s an additional singleton DecorationSettings which provides common settings for the decoration. Also there’s an additional second private API which must be implemented by a backend. This will allow us to use KDecoration2 in multiple places. I want to see it uses in KWin, but in future I’d also like to provide our decorations for QtWayland. For this I hope that KDecoration plugins can also be a solution.

Why Breeze is not the default window decoration

This week we finally released Plasma 5.0 including KWin 5.0 and also a new design called “Breeze”. While Breeze provides a window decoration, KWin still defaults to Oxygen and that’s for a good reason. As I had been asked quite often why that’s the case and on the other side got lots of feedback from disappointed users using the Breeze decoration I think it’s needed to explain in a blog post the technical background.

I start with explaining how our window decorations work in KWin 4. KWin is a so-called re-parenting window manager. This means the managed X11 window is put into another X11 window providing the windwow frame. In KWin we use a QWidget for the window frame. Thus we are also restricted to what QWidget provides us. Our window decoration API predates the Compositing support and this adds quite some restrictions to it. Our solution is to intercept all paint events on the decoration’s QWidget and suppress it, trigger a repaint of the compositor and in the rendering pass ensure the decoration widget repaints to a temp image which then gets copied into a texture to be rendered by the Compositor.

The Breeze window decoration theme is based on the Aurorae theme engine. As I’m the main author of Aurorae I can bash it in this blog post without feeling sorry about it :-) Aurorae was designed to make it very easy to style a decoration and to make use of the new added translucency features. Being a solution which could be used as a default decoration was never the aim. The idea was to allow users who want the customizability this feature while the majority of the users could use the faster native themes. Aurorae was never fast and will never be fast. Over the time the performance improved, especially thanks to using QML. But also in that case it was only usable with the raster graphics system in KWin 4 times.

Now in KWin 5 the usage of QML is the main problem which makes it difficult to use Aurorae at all. QtQuick uses the SceneGraph and uses QWindow instead of QWidget. That’s quite a bummer for our QWidget based API. We adjusted the internal usage to support QWindow based decorations but that was quite a tough road as there are differences in the behavior of the windows. As it’s no longer QWidget based our interception of paint events is broken and we needed a new solution for it. And this solution is even more ugly than the old one because QtQuick is nowadays rendering through OpenGL. Due to limitations in Qt’s OpenGL implementation (might be addressed in Qt 5.4) we cannot share with the OpenGL context used by QtQuick. But we need to get the content from the Aurorae window into our OpenGL texture. The solution is to render to a QOpenGLFrameBufferObject and read it back into a QImage just to upload back to a texture. Not only is this a huge overhead to copy the content from GPU to RAM and back to GPU it’s also wasting lots of memory. The frame buffer object has the same size as the window and that’s way larger than the actual window decoration. In case of a maximized window it’s not just the title bar area but the complete window. And that overhead exists for each window.

That alone might render Aurorae completely unusable. I’m currently using the Breeze theme and KWin needs more than 200 MB of RAM – not really acceptable. But the situation is even worse. With QWindow we don’t get to know which areas got updated. So whenever e.g. a button gets updated we have to repaint the complete window including the complete copy of the decoration content. Which especially in animation situations is quite a problem.

The last problem to mention is OpenGL. QtQuick is supposed to use a dedicated rendering thread, but Qt disables that for all Mesa drivers and instead uses the main thread. But that’s also the thread KWin’s compositing OpenGL context lives in. That’s quite a performance problem and also introduces lots of instability problems (might also be addressed in Qt 5.4).

Overall the situation is so bad that colleagues recommended to disable Aurorae overall in the 5.0 release. As we released with it you can see that I disagree in that point. There is hardware where it’s working quite fine – on my system it doesn’t matter that it uses lots of RAM and if your driver supports Qt’s threaded rendering the performance problems are mostly gone and also all stability problems are gone. So the situation hasn’t changed: for users who want to customize there is a solution but it might introduce a loss of performance. But as a default theme like Breeze it’s clearly not an option.

So what’s the road forward? I started implementing a new decoration API removing the restriction of the decoration being QWidget based and at the same time I started implementing the Breeze decoration with this new API. I hope that we can introduce this in KWin 5.1. I’ll write another blog post about it soon and also prepare lots of small and easy tasks for new developers to join in this effort and help making a kick-ass decoration solution for 5.1

Next Generation Klipper

A few weeks ago I contacted Thomas Pfeiffer with the idea to design a new user interface for Klipper in Plasma 5.1. Surprisingly he informed me that a discussion was already started in the KDE Forums. Which is awesome as that means there was already some ideas on how the user interface could look like. Last week the number of new bug reports for KWin get lower so I started to look into Klipper for 5.1.

The old Klipper

The user interface of Klipper is based on a context menu and this restricts the possible interaction patterns. The task of Klipper is to hold a history of clipboard items and allow the user to select an old clipboard item and make it the current clipboard content. For this a context menu is a good solution as it allows the user to just select an item, it gets synced to the clipboard and the menu closes.

But Klipper offers more than just the clipboard history. It can perform various actions on the clipboard content:

  • Edit the clipboard content
  • Show a QR-code for the clipboard content
  • Remove content from history
  • Invoke actions (e.g. open link in browser) on clipboard content

Due to the nature of the context menu as user interface these actions can only be performed on the current clipboard item. Technically there is no reason for this restriction, but the user interface requires it. This in turn makes the usage interaction cumbersome: to show the QR-code of a previous item one needs to open Klipper, select the item – Klipper closes, open Klipper again and select the action to show the QR-code.

Also a problem with the current Klipper is that it doesn’t integrate with the environment. It sits in the notification area, but opens a QWidget styled menu. This makes Klipper an odd item in the system tray behaving different to all other items.

How Klipper should work in Plasma

A clipboard history is of course an important part of a desktop shell and thus should be a first class citizen. The user interface needs to be integrate and this means the interface needs to be provided by a Plasmoid which needs to be added to the notification area. The interface would still show a list and this is best done by providing the data in the form of a QAbstractItemModel.

As there should only be one clipboard history manager, but at the same time perhaps several user interfaces for it (e.g. one panel per screen) the QAbstractItemModel holding the data needs to be provided by a DataEngine. So overall we need to separate the user interface (Plasmoid) from the data storage (DataEngine) and turn the existing Klipper in just being the data storage.

How Klipper works internally

Internally Klipper consists of a History with HistoryItems in a circular double-linked list with a marked first item in the circle. Whenever the History changes the context menu gets repopulated on next show. Whenever the first item in the History changes Klipper syncs this item into the clipboard. This means the complete logic of Klipper interacts only with the History class. Which makes it a nice and clean interface. In a simplified class diagram Klipper looks like the following:

For creating the DataEngine we need access to the History and all items in it and put it into a QAbstractItemModel. There are two possible solutions: connect the QAbstractItemModel to the existing History or use the QAbstractItemModel as the new storage for the History instead of the own double linked list. As the current use of the History is to just mark everything as dirty and then to re-populate connecting the model to the History doesn’t sound like a good suggestion. Instead I investigated in using the model as the storage end. The design is then modified to look like the following:

To achieve this transition I first created a unit test to ensure that my transition doesn’t break the existing code. Then I created the model from scratch as well covered with unit tests and in a third step I hooked it into the existing History. With this transition both the use cases of the existing code base and the new DataEngine can be satisfied.

DataEngine, Service and co

With the model in place it’s time to make it available to Plasma. The tool of choice is the DataEngine which allows to export a model and can provide a Service allowing us to interact with Klipper. Of course it would be possible to add invokables to the model, but that would kind of destroy the design as the model is only supposed to be the data store. A Service which then interacts with our existing Klipper API is way cleaner. The task of the Service is to start ServiceJobs which will in turn interact with Klipper. Overall this looks now like this:

The Plasmoid

The last and maybe most important part of the rework is the user interface in form of a new Plasmoid. But that’s also the part I’m least interested in (perfer to work on backend) and are hoping for help on it :-) Given that the current user interface can and should only be considered as a draft. But it’s fully functional and support text and image elements, a filter (note: klipper supported filtering for quite some time, just start typing) and all the actions. But now the actions are available on each item and not just the latest one. In the current state with a vertical panel it looks like this:

Be aware that this is material for Plasma 5.1 – it won’t be part of the upcoming release. Also I should point out that it’s still possible to run the stand-alone Klipper application and that no features are removed. All global shortcuts and actions are still supported.

Where are my systray icons?

One of the features no longer available in the upcoming Plasma 5 release is the xembed based system tray (for explanation see my previous blog post). This can result in some applications missing a system tray icon, but it shouldn’t happen. There are patches around for various toolkits which will turn the xembed icon into a status notifier item. Our KDE packagers were informed back in March about the upcoming change and which patches should be applied to which components.

In summary that is for the toolkits:

  • GTK2: needs libappindicator1 and all packages having an optional
    dependency to it should get compiled with it.
  • GTK3: needs libappindicator3-1 and all packages having an optional
    dependency to it should get compiled with it.
  • Qt4: needs sni-qt and a patch to Qt 4.8
  • Qt5: Won’t need adjustments starting with Qt 5.4, but with Qt 5.3 this commit should be cherry-picked.

For GTK there is also a new library to implement status notifiers available, for more information read Marco’s blog post on the topic.

Unfortunately not all distributions have included the patches yet. If for one of your applications the system tray icon is not available although it works on other distributions I recommend to create a bug report in your distribution against the affected package to show that these additional build dependencies are required.

In the worst case you could install a third-party dedicated xembed system tray application. An example is “wmsystemtray”, this one can start with:

wmsystemtray --non-wmaker --bgcolor white

and best also configure a KWin window rule to have it without decorations and on all desktops:

Description=Application settings for wmsystemtray
desktop=-1
desktoprule=2
noborder=true
noborderrule=2
skippager=true
skippagerrule=2
skipswitcher=true
skipswitcherrule=2
skiptaskbar=true
skiptaskbarrule=2
type=2
typerule=2
wmclass=wmsystemtray0 wmsystemtray
wmclasscomplete=true
wmclassmatch=1

KWin is no more

Now that I have your attention: the binary of KWin/5 just got renamed from “kwin” to “kwin_x11″. For you as a user nothing changes, the startup is adjusted to start kwin_x11 instead of kwin. Nothing else changed. The D-Bus interface is still org.kde.KWin, the config file is still “kwinrc”, etc. etc. Only if you start KWin manually remember to run “kwin_x11 –replace &” instead of “kwin –replace &”.

Say thanks to Hrvoje Senjan for preparing the patches to rename the binary and adjust all the places where the binary name is used.

DBus Activation for apps in prefix

On my systems I noticed that some services like kglobalaccel are not automatically started when logging into the system. This is on the one hand rather annoying on the other it could indicate a bug in our setup. So this morning I started to look into the issue with kglobalaccel.

Kglobalaccel is a service which is supposed to get started through dbus. My installation prefix is “/opt/kf5″ and so the service file gets installed to “/opt/kf5/share/dbus-1/services/org.kde.kglobalaccel.service” – that looks fine. After some investigation I figured out that dbus-daemon looks in $XDG_DATA_DIRS as a search path. Our startkde script adjusts $XDG_DATA_DIRS to include /opt/kf5/share before launching the dbus daemon. But when looking at the environment of the running dbus-daemon one could see the problem: it doesn’t use the set environment variable. The reason is obvious: dbus is nowadays started before the desktop environment gets started.

This means D-Bus doesn’t know where to look for the service files. To fix this create a file “/etc/dbus-1/session.d/plasma-next.conf” with the following content (adjust path as needed):

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <servicedir>/opt/kf5/share/dbus-1/services/</servicedir>
</busconfig>

Save, logout, login and kglobalaccel and others should auto start.

How to test and fix translations for frameworks 5 applications

With frameworks 5 the translation system changed quite a bit resulting in your application not being translated without any adjustments. In this blog post I want to highlight how you can test whether your application loads the translation correctly and how to fix it if not. First of all I recommend to read the general translation documentation for the KI18n framework.

Like with kdelibs4 there is a test language which wraps every translated string “foo” to “xxfooxx”. This language needs to get installed. For that follow the following steps:

mkdir i18n # create a directory for the checkout
cd i18n # change into it
svn co svn://anonsvn.kde.org/home/kde/trunk/l10n-kf5/scripts # check out scripts
svn co svn://anonsvn.kde.org/home/kde/trunk/l10n-kf5/x-test  # check out test language
./scripts/autogen.sh x-test # generate build system for test language
mkdir x-test-build # create build dir for test language
cd x-test-build # and change into it
cmake -DCMAKE_INSTALL_PREFIX=/opt/kf5/ ../x-test # adjust /opt/kf5/ to your kf5 install dir
make
make install

With these steps the language gets installed. Now you can run your application to test with the LANGUAGE environment variable. For this blog post I use kinfocenter as the test application:

LANGUAGE=x-test kinfocenter

As you can see kinfocenter is not yet translated properly:

Aus i18n-kf5

The first step is now to connect the application to the catalog. The catalog is the name of the .pot file in Messages.sh – in the case of our test application that is “kinfocenter”.

This is being done with the following call:

KLocalizedString::setApplicationDomain("kinfocenter");

This has to be done before calling any i18n call, so most likely it is in your main function and before the construction of QApplication. After doing this change our kinfocenter looks like that:

Aus i18n-kf5

That’s better but there is still a lot of untranslated code around. The reason for that is kinfocenter loads libraries to display the content and those libraries are not yet connected to the catalogs. In kdelibs4 time one did that through the insertCatalog function, now it needs to be done in the library.

The way is to add a definition for TRANSLATION_DOMAIN with the catalog as value in the CMakeLists.txt of the library. So for the info module in kinfocenter that’s:

# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_infosummary\")

And now our kinfocenter looks like that:

Aus i18n-kf5

Of course one needs to do these adjustments for each of the libraries.

Last but not least one needs to mention ui files. For those one needs to use ki18n_wrap_ui in the CMakeLists.txt.

The Quality of KWin/5 is in YOUR Hands!

This week we had the beta release for our upcoming release of the next iterations of our Plasma workspaces. This also includes KWin 5.0 which has the first major transition since the introduction of Compositing back in 2008. The changes in KWin are huge as we ported to Qt 5 and with that also to XCB and QtQuick2. Personally I comare it to having exchanged the engine, the tires, adding new spoilers and getting a new finish for our car. But after such a huge change there will be the one or other screw which needs to be tightened to get the fastest car in the race.

And that’s where we need YOU. We cannot find all the small issues. We need you as a tester to know what to fix. So please give a try to our beta, our daily packages and weekly isos and try as hard as possible to break KWin. I want that KWin 5.0 has at least the same quality as KWin 4.11 and I’m sure you want that, too.

Head over to David’s blog post for general testing instructions. Of course KWin bugs should be reported against product “kwin” on bugzilla.

Screenlocker architecture in Plasma Next

The 14.04 release of Unity unfortunately shipped with a few security vulnerabilities in the newly introduced screenlocker. As we will also ship a reworked screenlocker in Plasma Next I started to do another code audit, add more unit tests and try to make the code easier to understand and maintain. Furthermore I think it’s a good reason to explain how screenlockers work in general on X11 (and why it is easy to introduce security vulnerabilities) and the screenlocker in Plasma Next in particular. To make one thing clear: this post is not meant to shame Ubuntu for the issues. Some of these whoopies would have been possible in Plasma, too, and that’s the reason why I looked at the code again in more detail. On the other hand I think that our screenlocker in Plasma Next could be a solution for Unity’s use cases and I would appreciate if Ubuntu would adpot our solution.

What a screenlocker should protect

Before looking at how it works in X11, I shortly want to discuss what a screenlocker can protect and what is out of scope for a screenlocker. In general there are two tasks for a screenlocker:

  • Blocking input devices, so that an attacker cannot interact with the running session
  • Blanking the screen to prevent private information being leaked

The lock is hold till an authorization is provided (e.g. password). I’ll discuss in more detail what these authorizations are in the case of Plasma.

There are a few things the screenlocker cannot protect against:

  • Evil software already running under the user’s account
  • Attackers having access to a tty running under the same user

To explain the first problem we must remember that X11 is very bad from a security point of view. This adds a general limitation to what can be protected. Getting a key logger with X11 is extremely trivial, there are easier ways to get the password than to try to attack the locker.

The second problem goes in the same direction: if someone has access to a tty, he can install an X11 key logger. It will not get the password, but still it’s a huge problem. Also the attacker could reconfigure the locker or run a debugger on the lock process to just end the locker. Some of these problems can be mitigated by the distribution through hardening (e.g. SELinux).

I plan to harden the system against these two problems in a future release. Though given the general problems of X11 it will never be possible to completely solve these two problems on X11.

How screenlockers work in X11

X11 doesn’t really know the concept of a screenlocker. Thus one needs to use the concepts of X11 to try to get something like a screenlocker. The main features are grabbing the keyboard and grabbing the pointer. What’s important to know about these two X11 features is that only one X Client is allowed to grab the keyboard and pointer. If the keyboard or pointer is already grabbed the lock cannot be established. For example if a (context) menu is open the screen cannot be locked or if Present Windows is active.

Having the keyboard and pointer grabbed are essential to fulfill the first task of the screenlocker. This also shows why it’s so difficult to get a locker right. As soon as the process grabbing the keyboard goes away the lock is released. As soon as that happens the screen is unlocked. Thus there is an easy scenario to attack a screenlocker: get the lock process to crash and restart and try to grab the keyboard before the screenlocker is able to re-install the grab.

This is the problem Unity run in and to be honest we also almost run into this issue in the past. Thus a screenlocker implementation must be able to hold the keyboard grab during a crash. A lock file might not be sufficient. I will explain later how we made the screenlocker in Plasma crash resistant, so that the session will never be unlocked.

The second task is blanking the screen. This is done by creating a lock window and raise it on top of all windows and ensure that the lock window is always on top of all windows. Given the description one can notice that this is kind of a fragile process. Assume one has two processes trying to be on top of each other: they will constantly try to raise on top of the other. Something I once experienced by having the screen locked during session startup resulting in a race between login and lock screen. Again Wayland will improve the situation as the compositor (in our case KWin) will be aware of the screenlocker and will ensure the restrictions.

Screenlocker architecture in Plasma Next

The architecture for locking screens got simplified in Plasma Next. Support for screen savers got completely removed (fear not: we have plans for replacement, probably not in Plasma Next, but in a future release) and that helped a lot to trim down the architecture.

In Plasma Next the locking consists of three interacting processes:

  • KSLD in KSMServer
  • kscreenlocker_greet (greeter)
  • kcheckpass

While this might sound complex to have three processes it’s following the unix philosophy of one tool, one task. So let’s look at what the processes do.

KSLD

KSLD (for KScreenLocker Daemon) is a library used by KSMServer. KSMServer is our session server which gets started during session startup and keeps the session alive. If it crashes the session dies with it and you are returned to the login screen. KSLD is the main component of the screenlocker: it listens to the activation signal (e.g. global shortcut or logind), installs the X11 lock, blanks the screen and waits for the authorization to unlock the screen again.

At the moment KSLD has three authorization mechanisms:

  • User configurable grace time: any user input during the grace time interval immediately unlocks the screen
  • logind: listens to Unlock signal on the session’s object
  • greeter process: exits with exit code 0

The most complex authorization mechanism is the greeter. For that the greeter process needs to be started and is monitored by KSLD. If the greeter process crashes the lock is kept and the greeter process is started again. The authorization to unlock is provided by the exit code of the process. If it exits with 0 the screen gets unlocked, with any other code the greeter gets started again.

Of course we need to show the greeter – so far the screen is blanked and no window is allowed to go above the blanked window. To achieve this the greeter can set a special window property on its windows and ksld will raise those above the locker and forward input events to this X client.

Security note: this cannot protect against malicious software already running on the user’s session. A malicious software could set the same property and thus read the input events. I intend to change this for a future release to have a socket communication between ksld and the greeter to pass window information and input events. Obviously it’s a good idea to use the Wayland protocol for this task – also on X11.

kscreenlocker_greet

The second process in our architecture is kscreenlocker_greet which got partially already explained in the previous section. In Plasma it’s responsible for rendering the unlock screen interface and the session switching interface. The user interface is implemented using QML allowing us to easily adopt to new use cases – e.g. the unlock screen in Plasma Active is just a different QML package.

For future releases we have some ideas to improve the experience by allowing to run our normal wallpaper plugins (bringing back animations) and allowing some selected plasmoids to go on the lock screen. Of course we need to white list the plasmoids which are allowed to go on the lock screen to not expose private information or even allow to start processes. It would be a bad idea to add a terminal emulator as a plasmoid.

kcheckpass

As mentioned our architecture is following the “do one thing, do it right” approach and the task of the greeter is only to provide the user interface. It does not perform any password verification. For that it uses kcheckpass, which is a small terminal application to verify a provided user password. If the user clicks the unlock in the greeter kcheckpass is invoked and the password is passed to kcheckpass through a binary socket protocol. Kcheckpass communicates with PAM to verify the password and can pass back an authentication success, authentication error or further information for PAM modules needing further interaction like a fingerprint reader. These messages and authentication failure are passed back to the greeter ui. If the authentication is successful the greeter exits with exit code 0.

This concludes the look on the various components. I would encourage all readers to try to break the architecture before we have a release. I’m quite confident that the architecture is secure and also more secure than what we had in 4.x.

XScreenSaver

Last but not least I want to share some thoughts on XScreenSaver. Whenever an issue arises like the ones in Unity we can hear people claiming one should use XScreenSaver because it’s way more secure. Now personally I don’t believe in silver bullets – especially not if it comes to security. In the beginning of this long blog post I stated two tasks a screenlocker needs to provide and XScreenSaver can fail with the second: the screen content can be exposed. Consider for example the linked screenshot. For a screen saver of the last millennium this was a suitable solution, but not for an implementation where we want to focus on security.

As we can read in the section On Toolkit Dialogs the security of XScreenSaver is based on the fact of not using a GUI toolkit. While the argumentation sounds good, it fails to see the need of today’s desktop environments. Providing an unlock dialog which can be styled with XLib might be a solution for the 90ies but not in a world where we want to provide an awesome user experience. Today users also expect the current time, battery state and many more information on the lock screen. We need to provide accessibility features which is not possible in XScreenSaver. We need to use proper idle mechanism shared with other applications. We need DBus integration, inhibition (XScreenSaver doesn’t support this!) and logind integration. Not using toolkits also means to have to fix bugs which the toolkit would solve for you, this is again increasing the risk of broken code and crashes in the daemon. Just consider this piece of code I found in XScreenSaver:

/* It turns out that if we do setlocale (LC_ALL, "") here, people
    running in Japanese locales get font craziness on the password
    dialog, presumably because it is displaying Japanese characters
    in a non-Japanese font.  However, if we don't call setlocale()
    at all, then XLookupString() never returns multi-byte UTF-8
    characters when people type non-Latin1 characters on the
    keyboard.
   
    The current theory (and at this point, I'm really guessing!) is
    that using LC_CTYPE instead of LC_ALL will make XLookupString()
    behave usefully, without having the side-effect of screwing up
    the fonts on the unlock dialog.
   
    See https://bugs.launchpad.net/ubuntu/+source/xscreensaver/+bug/671923
    from comment #20 onward.
   
      -- jwz, 24-Sep-2011
*/

Now if you consider the architecture I explained the “problem” of the toolkit doesn’t matter at all. We are running an interpreted (QML) language which heavily uses OpenGL without introducing any security risks by using separate processes. If the application which holds the lock (and also heavily uses Qt) crashes the complete session goes down. In turn I think that the argumentation provided by the XScreenSaver maintainer doesn’t hold. Even more I haven’t seen anything about crash resistance like we have in Plasma to have the session getting killed if the lock process crashes. I’m not saying that this doesn’t exist (the code base is very large and I haven’t done a full audit) but I haven’t seen anything in the very prominent documentation about why it’s better.

Of course one could ask why we don’t work on XScreenSaver to improve it and make it work for our use cases. I don’t think that this is possible and at least I would not even try to. It’s quite clear that code using toolkits is not wanted. I also doubt that the needs of desktop environments like Plasma, GNOME Shell or Unity are understood at all. Let me quote the FAQ:

KDE suffers from the same brain damage as GNOME, above.

The only sensible (and secure) way to use a screen saver under KDE is to turn off KDE’s built-in screen saver, and use xscreensaver instead.

With that attitude I think it’s quite obvious why at least I see zero chances to use XScreenSaver in any desktop environment.