Browse Source

Support env vars in (un)locks; reset env vars for user commands; update docs

master
Pekka Helenius 4 years ago
parent
commit
e6566cfa72
2 changed files with 60 additions and 10 deletions
  1. +24
    -5
      doc/CONFIGURATION.md
  2. +36
    -5
      tools/pamusb-agent

+ 24
- 5
doc/CONFIGURATION.md View File

@ -244,6 +244,13 @@ Users
<tr> <tr>
<td>agent</td> <td>agent</td>
<td>env</td>
<td>Element</td>
<td>An environment variable for the command. For multiple variables use multiple env tags</td>
<td>cmd</td>
<td>Element</td>
<td>Agent command, associated with env tags in the same agent element</td>
<td>Element</td> <td>Element</td>
<td>Agent commands, for use with pamusb-agent</td> <td>Agent commands, for use with pamusb-agent</td>
</tr> </tr>
@ -257,12 +264,24 @@ Example:
<!-- When the user "scox" removes the usb device, lock the screen and pause <!-- When the user "scox" removes the usb device, lock the screen and pause
beep-media-player --> beep-media-player -->
<agent event="lock">gnome-screensaver-command --lock</agent>
<agent event="lock">beep-media-player --pause</agent>
<agent event="lock">
<env>DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus</env>
<env>HOME=/home/scox</env>
<cmd>gnome-screensaver-command --lock</cmd>
</agent>
<agent event="lock">
<cmd>beep-media-player --pause</cmd>
</agent>
<!-- Resume operations when the usb device is plugged back and authenticated --> <!-- Resume operations when the usb device is plugged back and authenticated -->
<agent event="unlock">gnome-screensaver-command --deactivate</agent>
<agent event="unlock">beep-media-player --play</agent>
<agent event="unlock">
<env>DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus</env>
<env>HOME=/home/scox</env>
<cmd>gnome-screensaver-command --deactivate</cmd>
</agent>
<agent event="unlock">
<cmd>beep-media-player --play</cmd>
</agent>
</user> </user>
``` ```
@ -299,7 +318,7 @@ Example:
Location of the configuration file 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. If you want to use a different location, you will have to use the `-c` flag.


+ 36
- 5
tools/pamusb-agent View File

@ -21,6 +21,7 @@ import pwd
import getopt import getopt
import signal import signal
import re import re
import subprocess
import syslog import syslog
import gi import gi
import threading import threading
@ -110,6 +111,12 @@ def usage():
os.path.basename(__file__)) os.path.basename(__file__))
sys.exit(1) sys.exit(1)
def runAs(uid, gid):
def set_id():
os.setuid(uid)
os.setgid(gid)
return set_id
import getopt import getopt
try: try:
@ -149,6 +156,9 @@ users = doc.findall('users/user')
def userDeviceThread(user): def userDeviceThread(user):
userName = user.get('id') userName = user.get('id')
uid = pwd.getpwnam(userName)[2]
gid = pwd.getpwnam(userName)[3]
os.environ = None
events = { events = {
'lock' : [], 'lock' : [],
@ -156,7 +166,19 @@ def userDeviceThread(user):
} }
for hotplug in user.findall('agent'): 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() deviceName = user.find('device').text.strip()
@ -174,9 +196,13 @@ def userDeviceThread(user):
if event == 'removed': if event == 'removed':
logger.info('Device "%s" has been removed, ' \ logger.info('Device "%s" has been removed, ' \
'locking down user "%s"...' % (deviceName, userName)) 'locking down user "%s"...' % (deviceName, userName))
for cmd in events['lock']:
for l in events['lock']:
cmd = l['cmd']
logger.info('Running "%s"' % cmd) logger.info('Running "%s"' % cmd)
os.system(cmd)
subprocess.run(cmd.split(), env=l['env'], preexec_fn=runAs(uid, gid))
logger.info('Locked.') logger.info('Locked.')
return return
@ -188,10 +214,15 @@ def userDeviceThread(user):
if not os.system(cmdLine): if not os.system(cmdLine):
logger.info('Authentication succeeded. ' \ logger.info('Authentication succeeded. ' \
'Unlocking user "%s"...' % userName) 'Unlocking user "%s"...' % userName)
for cmd in events['unlock']:
for l in events['unlock']:
cmd = l['cmd']
logger.info('Running "%s"' % cmd) logger.info('Running "%s"' % cmd)
os.system(cmd)
subprocess.run(cmd.split(), env=l['env'], preexec_fn=runAs(uid, gid))
logger.info('Unlocked.') logger.info('Unlocked.')
else: else:
logger.info('Authentication failed for device %s. ' \ logger.info('Authentication failed for device %s. ' \
'Keeping user "%s" locked down.' % (deviceName, userName)) 'Keeping user "%s" locked down.' % (deviceName, userName))


Loading…
Cancel
Save