Statistics
| Branch: | Revision:

root / snfOCCI / voms / __init__.py @ 0e9a6098

History | View | Annotate | Download (3.9 kB)

1
import collections
2
import commands
3
import ctypes
4
import os
5
import tempfile 
6

    
7
import M2Crypto
8

    
9
from snfOCCI.config import VOMS_CONFIG
10
import voms_helper
11
import exception
12

    
13
SSL_CLIENT_S_DN_ENV = "SSL_CLIENT_S_DN"
14
SSL_CLIENT_CERT_ENV = "SSL_CLIENT_CERT"
15
SSL_CLIENT_CERT_CHAIN_0_ENV = "SSL_CLIENT_CERT_CHAIN_0"
16

    
17

    
18
class VomsError(exception.Error):
19
    """Voms credential management error"""
20

    
21
    errors = {
22
        0: ('none', None),
23
        1: ('nosocket', 'Socket problem'),
24
        2: ('noident', 'Cannot identify itself (certificate problem)'),
25
        3: ('comm', 'Server problem'),
26
        4: ('param', 'Wrong parameters'),
27
        5: ('noext', 'VOMS extension missing'),
28
        6: ('noinit', 'Initialization error'),
29
        7: ('time', 'Error in time checking'),
30
        8: ('idcheck', 'User data in extension different from the real'),
31
        9: ('extrainfo', 'VO name and URI missing'),
32
        10: ('format', 'Wrong data format'),
33
        11: ('nodata', 'Empty extension'),
34
        12: ('parse', 'Parse error'),
35
        13: ('dir', 'Directory error'),
36
        14: ('sign', 'Signature error'),
37
        15: ('server', 'Unidentifiable VOMS server'),
38
        16: ('mem', 'Memory problems'),
39
        17: ('verify', 'Generic verification error'),
40
        18: ('type', 'Returned data of unknown type'),
41
        19: ('order', 'Ordering different than required'),
42
        20: ('servercode', 'Error from the server'),
43
        21: ('notavail', 'Method not available'),
44
    }
45

    
46
    http_codes = {
47
        5: (400, "Bad Request"),
48
        11: (400, "Bad Request"),
49
        14: (401, "Not Authorized"),
50
    }
51

    
52

    
53
def _get_cert_chain(ssl_info):
54
    """Return certificate and chain from the ssl info in M2Crypto format"""
55

    
56
    cert = ssl_info.get(SSL_CLIENT_CERT_ENV, "")
57
    chain = ssl_info.get(SSL_CLIENT_CERT_CHAIN_0_ENV, "")
58

    
59
    cert = M2Crypto.X509.load_cert_string(cert)
60
    aux = M2Crypto.X509.load_cert_string(chain)
61
    chain = M2Crypto.X509.X509_Stack()
62
    chain.push(aux)
63

    
64
    return (cert, chain)
65

    
66

    
67
def _get_voms_info(ssl_info):
68
    """Extract voms info from ssl_info and return dict with it."""
69

    
70
    try:
71
        cert, chain = _get_cert_chain(ssl_info)
72
    except M2Crypto.X509.X509Error as e:
73
        print e
74

    
75
    with voms_helper.VOMS(VOMS_CONFIG["vomsdir_path"],VOMS_CONFIG["ca_path"], VOMS_CONFIG["vomsapi_lib"]) as v:
76

    
77
        voms_data = v.retrieve(cert, chain)
78
        
79
        
80
        if not voms_data:
81
            print "error \n"
82
            raise VomsError(v.error.value)
83

    
84
        d = {}
85
        for attr in ('user', 'userca', 'server', 'serverca',
86
                     'voname',  'uri', 'version', 'serial',
87
                     ('not_before', 'date1'), ('not_after', 'date2')):
88
            if isinstance(attr, basestring):
89
                d[attr] = getattr(voms_data, attr)
90
            else:
91
                d[attr[0]] = getattr(voms_data, attr[1])
92

    
93
        d["fqans"] = []
94
        for fqan in iter(voms_data.fqan):
95
            if fqan is None:
96
                break
97
            d["fqans"].append(fqan)
98

    
99
    return d
100

    
101

    
102
def _split_fqan(fqan):
103
        """
104
        gets a fqan and returns a tuple containing
105
        (vo/groups, role, capability)
106
        """
107
        l = fqan.split("/")
108
        capability = l.pop().split("=")[-1]
109
        role = l.pop().split("=")[-1]
110
        vogroup = "/".join(l)
111
        return (vogroup, role, capability)
112
    
113

    
114
def _split_fqan(fqan):
115
        """
116
        gets a fqan and returns a tuple containing
117
        (vo/groups, role, capability)
118
        """
119
        l = fqan.split("/")
120
        capability = l.pop().split("=")[-1]
121
        role = l.pop().split("=")[-1]
122
        vogroup = "/".join(l)
123
        return (vogroup, role, capability)
124

    
125

    
126
def authenticate(ssl_data):
127
    try:
128
        voms_info = _get_voms_info(ssl_data)
129
    except VomsError as e:
130
        raise e
131

    
132
    user_dn = voms_info["user"]
133
    user_vo = voms_info["voname"]
134
    user_fqans = voms_info["fqans"]
135

    
136
    return user_dn, user_vo, user_fqans