From e6566cfa724a88f7ab94b1a6e7c17f4fa8444013 Mon Sep 17 00:00:00 2001 From: Pekka Helenius Date: Thu, 21 May 2020 18:20:27 +0300 Subject: [PATCH] Support env vars in (un)locks; reset env vars for user commands; update docs --- doc/CONFIGURATION.md | 29 ++++++++++++++++++++++++----- tools/pamusb-agent | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index 0613e0b..a5943a1 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -244,6 +244,13 @@ Users agent + env + Element + An environment variable for the command. For multiple variables use multiple env tags + + cmd + Element + Agent command, associated with env tags in the same agent element Element Agent commands, for use with pamusb-agent @@ -257,12 +264,24 @@ Example: - gnome-screensaver-command --lock - beep-media-player --pause + + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus + HOME=/home/scox + gnome-screensaver-command --lock + + + beep-media-player --pause + - gnome-screensaver-command --deactivate - beep-media-player --play + + DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus + HOME=/home/scox + gnome-screensaver-command --deactivate + + + beep-media-player --play + ``` @@ -299,7 +318,7 @@ Example: Location of the configuration file ---------------------------------- -By default, pam_usb.so and its tools will look for the configuration file at `/etc/security/pam_usb.conf`. +By default, pam_usb.so and its tools will look for the configuration file at `/etc/security/pam_usb.conf`. If you want to use a different location, you will have to use the `-c` flag. diff --git a/tools/pamusb-agent b/tools/pamusb-agent index 759ba85..0cec85d 100755 --- a/tools/pamusb-agent +++ b/tools/pamusb-agent @@ -21,6 +21,7 @@ import pwd import getopt import signal import re +import subprocess import syslog import gi import threading @@ -110,6 +111,12 @@ def usage(): os.path.basename(__file__)) sys.exit(1) +def runAs(uid, gid): + def set_id(): + os.setuid(uid) + os.setgid(gid) + return set_id + import getopt try: @@ -149,6 +156,9 @@ users = doc.findall('users/user') def userDeviceThread(user): userName = user.get('id') + uid = pwd.getpwnam(userName)[2] + gid = pwd.getpwnam(userName)[3] + os.environ = None events = { 'lock' : [], @@ -156,7 +166,19 @@ def userDeviceThread(user): } for hotplug in user.findall('agent'): - events[hotplug.get('event')].append(hotplug.text) + henvs = {} + + for henv in hotplug.findall('env'): + henv_var = re.sub(r'^(.*?)=.*$', '\\1', henv.text) + henv_arg = re.sub(r'^.*?=(.*)$', '\\1', henv.text) + henvs[henv_var] = henv_arg + + events[hotplug.get('event')].append( + { + 'env': henvs, + 'cmd': hotplug.find('cmd').text + } + ) deviceName = user.find('device').text.strip() @@ -174,9 +196,13 @@ def userDeviceThread(user): if event == 'removed': logger.info('Device "%s" has been removed, ' \ 'locking down user "%s"...' % (deviceName, userName)) - for cmd in events['lock']: + + for l in events['lock']: + cmd = l['cmd'] + logger.info('Running "%s"' % cmd) - os.system(cmd) + subprocess.run(cmd.split(), env=l['env'], preexec_fn=runAs(uid, gid)) + logger.info('Locked.') return @@ -188,10 +214,15 @@ def userDeviceThread(user): if not os.system(cmdLine): logger.info('Authentication succeeded. ' \ 'Unlocking user "%s"...' % userName) - for cmd in events['unlock']: + + for l in events['unlock']: + cmd = l['cmd'] + logger.info('Running "%s"' % cmd) - os.system(cmd) + subprocess.run(cmd.split(), env=l['env'], preexec_fn=runAs(uid, gid)) + logger.info('Unlocked.') + else: logger.info('Authentication failed for device %s. ' \ 'Keeping user "%s" locked down.' % (deviceName, userName))