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
|