1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
9 """Log an authentication result to syslogd"""
10 syslog.openlog(facility=syslog.LOG_AUTH)
11 syslog.syslog('arvados_pam: ' + msg)
14 class AuthEvent(object):
15 def __init__(self, config, service, client_host, username, token):
17 self.service = service
18 self.client_host = client_host
19 self.username = username
27 """Return truthy IFF credentials should be accepted."""
30 self.api_host = self.config['arvados_api_host']
31 self.arv = arvados.api('v1', host=self.api_host, token=self.token,
32 insecure=self.config.get('insecure', False),
35 vmname = self.config['virtual_machine_hostname']
36 vms = self.arv.virtual_machines().list(filters=[['hostname','=',vmname]]).execute()
37 if vms['items_available'] > 1:
38 raise Exception("lookup hostname %s returned %d records" % (vmname, vms['items_available']))
39 if vms['items_available'] == 0:
40 raise Exception("lookup hostname %s not found" % vmname)
42 if vm['hostname'] != vmname:
43 raise Exception("lookup hostname %s returned hostname %s" % (vmname, vm['hostname']))
44 self.vm_uuid = vm['uuid']
46 self.user = self.arv.users().current().execute()
49 ['link_class','=','permission'],
50 ['name','=','can_login'],
51 ['head_uuid','=',self.vm_uuid],
52 ['tail_uuid','=',self.user['uuid']]]
53 for l in self.arv.links().list(filters=filters, limit=10000).execute()['items']:
54 if (l['properties']['username'] == self.username and
55 l['tail_uuid'] == self.user['uuid'] and
56 l['head_uuid'] == self.vm_uuid and
57 l['link_class'] == 'permission' and
58 l['name'] == 'can_login'):
59 return self._report(True)
61 return self._report(False)
63 except Exception as e:
64 return self._report(e)
66 def _report(self, result):
67 """Log the result. Return truthy IFF result is True.
69 result must be True, False, or an exception.
72 auth_log(self.message())
76 """Return a log message describing the event and its outcome."""
77 if isinstance(self.result, Exception):
78 outcome = 'Error: ' + repr(self.result)
79 elif self.result == True:
84 if len(self.token) > 40:
85 log_token = self.token[0:15]
87 log_token = '<invalid>'
89 log_label = [self.service, self.api_host, self.vm_uuid, self.client_host, self.username, log_token]
91 log_label += [self.user.get('uuid'), self.user.get('full_name')]
92 return str(log_label) + ': ' + outcome