⌨ Labor omnia vincit ☮

pam-accesscontrol: PAM-based access control system written in python

Posted in python, Qt, security by anaumov on 27.12.2017

In traditional UNIX/Linux authentication there is not much granularity available in limiting a user’s ability to login. For example, how would you limit the number of users from a specific group? What if you want to allow some users to log in from a specific host, but disallow all others from a same host? Firewall will not help at this point. What if you want to allow SSH for someone, but not X- or login sessions on tty? And… what if you want to be able to decide about allowing SSH for someone at the same moment when connection will be established?

PAM, or pluggable authentication modules, allows for you just this sort of functionality (and more) without the need to patch all your services. PAM is flexible enough to provide solution for all of the above listed issues. All what you need at this point is just implement a new PAM-plugin for your needs.
Some times ago I came across pam_python — a PAM module that lets you write PAM modules in python. During paying with pam-python I implemented my own plugin as a hobby. At the beginning that was just notification window about every new incoming SSH connection. After that I added possibility to allow or denied every new established SSH connection by asking the owner of the X session (that was implemented just for desktop users in mind, of course). Next – define the list of users who may to login any time, who should wait for confirmation and who should never get the shell on my machine. I came on idea to put these lists to the config file. Project grew quickly. Now I would like to introduce it, show the sources and invite everyone (who love coding) to take a part of the development 😉


I called it pam-accesscontrol. Before we start I would like to remind you, that it was implemented as a hobby project just for fun and it’s still unstable, i.e. can broke something on your system. “Someting” is nothing others as a possibility to login via tty/login(1), SSH and X (supported login managers: kdm, gdm, xdm, sddm, lightdm). So, you can just look at the source code or, if you really know what you’re doing, install the package.

To be able to understand how PAM and pam-accesscontrol communicate with other, take a look at doc-page where you can find the list of pam-python methods which are nothing other then a interface for Linux PAM APIs. Every PAM event like open_session, close_session, authenticate, etc. will call appropriate pam-python method. This method will call appropriate pam-accesscontrol function.
For example, OpenSSH: by using password authentication procedure PAM calls pam_authenticate function, which call pam-python’s pam_sm_authenticate function. You just need to implement pam_sm_authenticate-method in your plugin to intercept further steps in the authentication process. Pam-python is just a “bridge” between PAM and pam-accesscontrol:

As you can see, we also should tell PAM (add configuration to files in /etc/pam.d/ directory) to call plugin in some necessary cases. Necessary cases are services like, for example, sshd or login (depend on our wishes) and events like auth, session, etc.
Below you can see how will be configured PAM during pam-accesscontrol installation:

for i in "sddm" "login" "sshd" "lightdm" "xdm" "kdm" "gdm"; do
    if [ -f "/etc/pam.d/$i" ]; then
      echo ""
      echo "#PAM-ACCESSCONTROL configuration" >> "/etc/pam.d/$i"
      echo "auth        required     pam_python.so accesscontrol.py" >> "/etc/pam.d/$i"
      echo "session     required     pam_python.so accesscontrol.py" >> "/etc/pam.d/$i"
      echo \[DONE\] successfully configured: $i

List of all available PAM modules can be found in /lib/$(arch)-linux-gnu/security/ directory. After installiing pam-python package pam-python.so file should be there and after installing pam-accesscontrol package — accesscontrol.py script.


Pam-accesscontrol’s behavior depend on its config file. You add rules for SSH, XDM or TTY services. It’s similar to iptables rules: by an authenticate new user or creating new session, pam-accesscontrol will read config file, parse it and try to make a decision. Actually, pam-accessconfig is nothing else then just a parser. It’s possible to close access for everybody and specify in what case and for whem it will be open, or vice versa — just define who should have no access. At the end decision has made by pam-accesscontrol will be returned to PAM.

Right after package installing it has just one rule in its config file: DEFAULT:OPEN, i.e. access open for everyone. If this DEFAULT variable will be not set in config file, pam-accesscontrol initialize it with CLOSE value.

Let me show some configuration examples.

> cat /etc/pam-accesscontrol/pam-accesscontrol.conf

XDM OPEN USER bob,alice
TTY OPEN USER bob,alice

First line of this configuration closes access for all users. After that we open SSH for all users from lp and users groups (it supports LDAP groups); open access to the host via login manager for users bob and alice; open access via getty for users bob and alice. Pretty easy. Every rule should have exactly 4 fields. If rule is wrong, it will be just ignored.

It’s possible to set limit for number of users from specific group.

SSH NUMBER GROUP users:2,lp:3

For example, this line sets limit to 2 for group users and to 3 for group lp. In other words, new SSH connection will be possible for users from group lp, if only 2 or less users will be logged on this system at the same time.

It’s also possible to configure it so that it will ask you for every new incoming SSH connection. With this line in config file everyone from group lp will wait for your confirmation:


It means

  1. user should to login via SSH (know password or has ssh-key)
  2. after that you should allow this connection

It calls QMessageBox from PyQt5 that returns 0 or 1 to pam-accesscontrol depend on your choice. This value will be interpreted as allow or not allow. By the way, if there is no active Xorg session, pam-accesscontrol will not be able to ask you… so in this case this will be interpreted as an OPEN rule. Also keep in mind that pam-accesscontrol ask owner of the Xorg session only for the first SSH incoming connection. Remote user would like, for example, to copy 100 files on its host; in that case also just one confirmation at the begging will be needed.

Xorg session owner also will be informed when remote user (whose SSH session was confirmed through QMessageBox) ends its SSH session.


Pam-accesscontrol uses syslog. It creates logs after every trying to login. As usual, on systemd-based systems you can use journalctl(1). Also some logs can be found in /var/log/auth.log (authentication phase) and /var/log/syslog files. By default there is not so much information. For debugging and during development it’s a good idea to enable debug/verbose mode. Add DEBUG:True to the config file and it will put much more info about why it made this or that decision.
It also creates its own log file /var/log/pam-accesscontrol-YEAR-MON.log where is stored short statistic about when, who, via which interface tried to login and also — was it successful or not.

Use ldd(1) to check PAM compatibility for supported interfaces:

# ldd $(which sshd) | grep pam
        libpam.so.0 => /lib64/libpam.so.0 (0x00007f82cdfff000)
# ldd $(which login) | grep pam
        libpam.so.0 => /lib64/libpam.so.0 (0x00007fee7f3c9000)
        libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x00007fee7f1c5000)

openSUSE factory :: cool-retro-term

Posted in Qt, SuSE [ru] by anaumov on 14.09.2014


The Qt Project and Digia have released Qt 5.0

Posted in Qt by anaumov on 19.12.2012

The Qt Project is proud to announce the final release of Qt 5. It is the latest version of the Qt C++ UI framework and the foundation for a new way of developing applications, where Qt Quick is in the center of Qt. Qt 5 continues to offer all of the power of native Qt C++ enabling highly sophisticated user experiences, offering applications the full capabilities of OpenGL/OpenGL ES graphics acceleration.


Migration to PySide

Posted in python, Qt by anaumov on 08.09.2012

Как вы знаете, в начале этого года официально закончилась миграция PySide в инфраструктуру Qt project.

В связи с этим я решил начать переписывать все свои PyQt4 приложения на PySide. Есть несколько способов оптимизации кода для работы с обоими bindings, но это по моему мнению добавление “костылей”, которые только испортят красоту кода вашего проекта. К тому же я не вижу никаких причин оставаться на PyQt4. Похоже, что большинство подсистем будет мигрированно в PySide в ближайшем будущем.

О различиях в API можно проконсультироваться в вики, на странице Differences_Between_PySide_and_PyQt.
Кстати, книга Rapid GUI Programming with Python and Qt хоть и рассматривает PyQt4 (все примеры в книге), будет так же полезна PySide программистам. Как я уже сказал, различия в API есть, но миграция не должна вызвать больших проблем.

Qt Developer Days 2010

Posted in fun, Qt by anaumov on 04.06.2010

Сегодня я получил email с приглашением на “Qt Developer Days 2010” (я проходил предрегистрацию). Конференция пройдет в Мюнхене с 11 по 13 октября и в Сан Франциско с 1 по 3 ноября этого года. Она является пожалуй самым масштабным и лучшим Qt/Nokia-мероприятием. Прошлый раз, в 2009 году, там было около 700 человек! Это очень интересная конференция для меня, как для разработчика KDE.

К сожаленью, она требует регистрации, которая далеко не бесплатная. Да, в отличии от FOSDEM или openSUSE Conference, тут придется заплатить 499€ за 3 дня (и это еще с тем условием, что я заплачу до 15 сентября, если же познее, то 699€).

Кстати, вот вроде официальное видео с прошлого года. Много приветливых и дружелюбных людей:

Ок, я знаю, что Qt/Nokia готовит прекрасный кофе, но все равно это слишком дорого для студентов как я. В общем, не остается ничего другого, как ждать openSUSE Conference 2010, и встретиться с разработиками Qt/KDE там.

Qt 4.7.0 Beta1

Posted in Qt, SuSE [ru] by anaumov on 09.05.2010

Qt 4.7.0 Beta1 теперь доступна для загрузки с официальной страницы. Бета доступна в обеих типах пакетов (.zip и tar.gz форматы), а так же в виде бинарных пакетов (для Mac Cacao, Mac Carbon, MinGW 4.4.0 и Visual Studio 2008).

Обратите внимание, что незначительные изменения в названии Mac пакетов по сравнению с Qt 4.6.x – пакеты для Carbon теперь под названием “qt-mac-carbon-opensource-*”, а пакеты для Cacao теперь под названием “qt-mac-opensource-* “. Это еще раз показывает, что Cacao в настоящее время является основной платформой Mac для Qt. Бинарные пакеты для Carbon больше поддерживаться не будут, начиная с версии Qt 4.8, однако будут по-прежнему поддерживать серию 4.7.x.

Для тех, кто пожелает использовать открытые “v4.7.0-beta1” git-репозитории из http://qt.gitorious.org/, то они пока не готовы, но будут доступны в ближайшее время.

Цель бета-релиза, как и стоило того ожидать, в том, чтобы помочь собрать feedback пользователей о качестве 4,7, особенно с точки зрения стабильности, производительности и качества документации. Это позволит разработчикам сосредоточить усилия на наиболее частных ошибках, а так же сделать вывод о том, будет ли следующая версия очередной бетой, или же Release Candidate.

Если кто-то хочет оставить свой feedback, вы можете сделать это с помощью Qt Bug Tracker. Если вы хотите внести свой вклад (в виде патча/кода), документации или автотестов для Qt, все сведения, необходимые для начала работы можно найти по адресу: http://qt.gitorious.org/.