1
|
# -*- coding: utf-8 -*-
|
2
|
#
|
3
|
# UnivNautes
|
4
|
# Copyright (C) 2014 Entr'ouvert
|
5
|
#
|
6
|
# This program is free software: you can redistribute it and/or modify it under
|
7
|
# the terms of the GNU Affero General Public License as published by the Free
|
8
|
# Software Foundation, either version 3 of the License, or (at your option) any
|
9
|
# later version.
|
10
|
#
|
11
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
14
|
# details.
|
15
|
#
|
16
|
# You should have received a copy of the GNU Affero General Public License
|
17
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
|
19
|
import sys
|
20
|
import re
|
21
|
import xml.etree.ElementTree as ET
|
22
|
from operator import itemgetter
|
23
|
|
24
|
from django.conf import settings
|
25
|
|
26
|
def root():
|
27
|
with open(settings.CONFIG_XML,'r') as f:
|
28
|
x = ET.fromstring(f.read())
|
29
|
return x
|
30
|
|
31
|
def laxint(s):
|
32
|
try:
|
33
|
return int(s)
|
34
|
except:
|
35
|
return 0
|
36
|
|
37
|
def get_ca(caref):
|
38
|
for ca in root().findall('ca'):
|
39
|
if ca.find('refid').text == caref:
|
40
|
crt = ca.find('crt')
|
41
|
if crt is not None:
|
42
|
crt = crt.text.decode('base64')
|
43
|
prv = ca.find('prv')
|
44
|
if prv is not None:
|
45
|
prv = prv.text.decode('base64')
|
46
|
return {
|
47
|
'caref': caref,
|
48
|
'crt': crt,
|
49
|
'prv': prv,
|
50
|
}
|
51
|
return None
|
52
|
|
53
|
def get_cert(certref):
|
54
|
for cert in root().findall('cert'):
|
55
|
if cert.find('refid').text == certref:
|
56
|
crt = cert.find('crt')
|
57
|
if crt is not None:
|
58
|
crt = crt.text.decode('base64')
|
59
|
prv = cert.find('prv')
|
60
|
if prv is not None:
|
61
|
prv = prv.text.decode('base64')
|
62
|
caref = cert.find('caref')
|
63
|
if caref is not None:
|
64
|
caref = caref.text
|
65
|
descr = cert.find('descr')
|
66
|
if descr is not None:
|
67
|
descr = descr.text
|
68
|
return {
|
69
|
'certref': caref,
|
70
|
'descr': descr,
|
71
|
'caref': caref,
|
72
|
'crt': crt,
|
73
|
'prv': prv,
|
74
|
}
|
75
|
return None
|
76
|
|
77
|
def get_saml_cps():
|
78
|
'''
|
79
|
returns a list of captive portal with SAML auth_method
|
80
|
'''
|
81
|
xml_cps = root().find('captiveportal')
|
82
|
if xml_cps is None:
|
83
|
return []
|
84
|
cps = []
|
85
|
for xml_cp in xml_cps:
|
86
|
name = xml_cp.tag
|
87
|
if xml_cp.find('enable') is None:
|
88
|
continue
|
89
|
auth = xml_cp.find('auth_method')
|
90
|
if auth is None or auth.text != 'saml':
|
91
|
continue
|
92
|
auth = auth.text
|
93
|
timeout = xml_cp.find('timeout')
|
94
|
if timeout is not None:
|
95
|
timeout = laxint(timeout.text)
|
96
|
else:
|
97
|
timeout = 0
|
98
|
idletimeout = xml_cp.find('idletimeout')
|
99
|
if idletimeout is not None:
|
100
|
idletimeout = laxint(idletimeout.text)
|
101
|
else:
|
102
|
idletimeout = 0
|
103
|
httpsname = xml_cp.find('httpsname')
|
104
|
if httpsname is not None:
|
105
|
httpsname = httpsname.text
|
106
|
cps.append({
|
107
|
'name': name,
|
108
|
'httpsname': httpsname,
|
109
|
'auth_method': auth,
|
110
|
'timeout': timeout,
|
111
|
'idletimeout': idletimeout,
|
112
|
})
|
113
|
cps.sort(cps, key=itemgetter('name'))
|
114
|
return cps
|
115
|
|
116
|
def get_sp():
|
117
|
sp = root().find('univnautes/sp')
|
118
|
if sp is None:
|
119
|
return None
|
120
|
|
121
|
certref = sp.find('certref')
|
122
|
if certref is not None:
|
123
|
saml_cert = get_cert(certref.text)
|
124
|
else:
|
125
|
saml_cert = None
|
126
|
|
127
|
defaultidps = sp.find('defaultidps')
|
128
|
if defaultidps is None:
|
129
|
defaultidps = []
|
130
|
else:
|
131
|
defaultidps = defaultidps.text or ''
|
132
|
defaultidps = defaultidps.decode('base64').decode('iso-8859-1').splitlines()
|
133
|
defaultidps = [ l for l in defaultidps if not re.match('^\s*(#|$)', l) ]
|
134
|
|
135
|
geolocations = sp.find('geolocations')
|
136
|
if geolocations is None:
|
137
|
geolocations = []
|
138
|
else:
|
139
|
geolocations = geolocations.text or ''
|
140
|
geolocations = geolocations.decode('base64').decode('iso-8859-1').splitlines()
|
141
|
geolocations = [ l for l in geolocations if not re.match('^\s*(#|$)', l) ]
|
142
|
geoinitialbounds = sp.find('geoinitialbounds')
|
143
|
if geoinitialbounds is not None:
|
144
|
geoinitialbounds = geoinitialbounds.text
|
145
|
|
146
|
cps = get_saml_cps()
|
147
|
if cps:
|
148
|
cp = cps[0]
|
149
|
else:
|
150
|
cp = {}
|
151
|
return { 'saml_cert': saml_cert,
|
152
|
'cp': cp,
|
153
|
'ui': {
|
154
|
'defaultidps': defaultidps,
|
155
|
'geolocations': geolocations,
|
156
|
'geoinitialbounds': geoinitialbounds,
|
157
|
},
|
158
|
}
|
159
|
|
160
|
def get_federations():
|
161
|
"""
|
162
|
<federation>
|
163
|
<enable/>
|
164
|
<codename>renater_test</codename>
|
165
|
<refid>fed_53d1161955a26</refid>
|
166
|
<descr><![CDATA[Renater TEST Federation]]></descr>
|
167
|
<url>https://federation.renater.fr/test/renater-test-metadata.xml</url>
|
168
|
<certref>53d115fac567b</certref>
|
169
|
</federation>
|
170
|
"""
|
171
|
xml_federations = root().find('univnautes/federations')
|
172
|
if xml_federations is None:
|
173
|
return []
|
174
|
xml_federations = xml_federations.findall('federation')
|
175
|
federations = []
|
176
|
for xml_federation in xml_federations:
|
177
|
if xml_federation.find('enable') is None:
|
178
|
continue
|
179
|
codename = xml_federation.find('codename')
|
180
|
if codename is not None:
|
181
|
codename = codename.text
|
182
|
url = xml_federation.find('url')
|
183
|
if url is not None:
|
184
|
url = url.text
|
185
|
descr = xml_federation.find('descr')
|
186
|
if descr is not None:
|
187
|
descr = descr.text
|
188
|
certref = xml_federation.find('certref')
|
189
|
if certref is not None:
|
190
|
signcert = (get_cert(certref.text) or {}).get('crt')
|
191
|
else:
|
192
|
signcert = None
|
193
|
federations.append({
|
194
|
'codename': codename,
|
195
|
'url': url,
|
196
|
'signcert': signcert,
|
197
|
'descr': descr,
|
198
|
})
|
199
|
return federations
|
200
|
|
201
|
def get_whitelists():
|
202
|
"""
|
203
|
<whitelist>
|
204
|
<refid>whitelist_53d12b4ba06c2</refid>
|
205
|
<codename>eduspot</codename>
|
206
|
<descr><![CDATA[Whitelist eduspot]]></descr>
|
207
|
<url>https://www.cru.fr/eduspot/whitelist-eduspot.txt</url>
|
208
|
<caref>53d1166cc8bae</caref>
|
209
|
</whitelist>
|
210
|
"""
|
211
|
xml_whitelists = root().find('univnautes/whitelists')
|
212
|
if xml_whitelists is None:
|
213
|
return []
|
214
|
xml_whitelists = xml_whitelists.findall('whitelist')
|
215
|
whitelists = []
|
216
|
for xml_whitelist in xml_whitelists:
|
217
|
refid = xml_whitelist.find('refid')
|
218
|
if refid is not None:
|
219
|
refid = refid.text
|
220
|
codename = xml_whitelist.find('codename')
|
221
|
if codename is not None:
|
222
|
codename = codename.text
|
223
|
descr = xml_whitelist.find('descr')
|
224
|
if descr is not None:
|
225
|
descr = descr.text
|
226
|
url = xml_whitelist.find('url')
|
227
|
if url is not None:
|
228
|
url = url.text
|
229
|
caref = xml_whitelist.find('caref')
|
230
|
if caref is not None:
|
231
|
cacert = (get_ca(caref.text) or {}).get('crt')
|
232
|
else:
|
233
|
cacert = None
|
234
|
whitelists.append({
|
235
|
'id': refid,
|
236
|
'codename': codename,
|
237
|
'url': url,
|
238
|
'cacert': cacert,
|
239
|
'descr': descr,
|
240
|
})
|
241
|
return whitelists
|
242
|
|