Projet

Général

Profil

Télécharger (3,28 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / usr / local / univnautes / sp / sp / auth.py @ 7f7705db

1
# -*- encoding: utf-8 -*-
2

    
3
import subprocess
4
import syslog
5
import xml.etree.ElementTree
6

    
7
from django.conf import settings
8
from django.contrib import messages
9

    
10
from authentic2.authsaml2 import signals
11

    
12
def user_login_cb(sender, request, attributes={}, **kwargs):
13
    if request and request.user.is_anonymous():
14
        return
15

    
16
    cpzone = request.META.get('HTTP_X_PFSENSE_CPZONE') or '';
17
 
18
    if 'displayName' in attributes:
19
        request.session['display_name'] = attributes['displayName'][0]
20

    
21
    nameid = 'nameID:%s' % attributes['__nameid']
22
    # use eduPersonTargetedID (OID 1.3.6.1.4.1.5923.1.1.1.10), fallback to __nameid/__issuer
23
    try:
24
        if 'eduPersonTargetedID' in attributes:
25
            attrkey = 'eduPersonTargetedID'
26
        else:
27
            attrkey = ('urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri')
28
        eduPersonTargetedID_xml = xml.etree.ElementTree.fromstring(attributes[attrkey][0])
29
        eduPersonTargetedID = 'eduPersonTargetedID:%s' % eduPersonTargetedID_xml.text
30
        eduPersonTargetedID_NameQualifier = eduPersonTargetedID_xml.attrib['NameQualifier']
31
    except:
32
        eduPersonTargetedID = nameid
33
        eduPersonTargetedID_NameQualifier = attributes['__issuer']
34

    
35
    # log needs eduPersonTargetedID + transientID + idp
36
    username = eduPersonTargetedID + '|' + eduPersonTargetedID_NameQualifier
37

    
38
    # TODO : blacklist
39

    
40
    ip = request.META['REMOTE_ADDR']
41

    
42
    # univnautes idp returns univnautesPrivileges attribute (a list)
43
    multiple = 0
44
    privileges = attributes.get((u'univnautesPrivileges', u'urn:oasis:names:tc:SAML:2.0:attrname-format:basic'), [])
45
    if 'univnautes-idp-multiple' in privileges:
46
       multiple = 1
47

    
48
    cmd = [ c % {
49
            'cpzone': cpzone,
50
            'ip': ip,
51
            'username': username,
52
            'nameid': nameid,
53
            'multiple': multiple,
54
            } for c in settings.UNIVNAUTES_CP_ALLOW_CMD ]
55

    
56
    if settings.DEBUG:
57
        syslog.openlog("sp/auth", syslog.LOG_PID)
58
        syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_DEBUG , 'meta: %r' % request.META)
59
        syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_DEBUG , "cmd: %r" % ' '.join(cmd))
60

    
61
    # open the firewall for this client
62
    try:
63
        p = subprocess.Popen(cmd, close_fds=True,
64
                        stdin=subprocess.PIPE,
65
                        stdout=subprocess.PIPE,
66
                        stderr=subprocess.PIPE)
67
    except OSError, e:
68
        request.session['pfsenseid'] = 'ERROR'
69
        messages.error(request, u"Erreur : OSError %s" % e)
70
        syslog.openlog("sp/auth", syslog.LOG_PID)
71
        syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO , "ERROR: OSError %s" % e)
72
        return False
73
    stdout, stderr = p.communicate()
74
    if p.returncode != 0:
75
        request.session['pfsenseid'] = 'ERROR'
76
        messages.error(request, u"Erreur : returncode=%d" % p.returncode)
77
        syslog.openlog("sp/auth", syslog.LOG_PID)
78
        syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO , "ERROR: returncode=%d" % p.returncode)
79
        return False
80
    # cp_allow returns the pfsense CP sessionid on stdout : store it in django session
81
    request.session['pfsenseid'] = stdout
82
    request.session['prefered_idp'] = attributes['__issuer']
83
    return True
84

    
85
signals.auth_login.connect(user_login_cb, dispatch_uid='authentic2.idp')
86

    
(2-2/8)