1
1
#!/usr/bin/env python
2
2
import argparse
3
3
import base64
4
- import xmldsig as ds
5
4
import re
6
5
import logging
7
6
import time
10
9
from urlparse import parse_qs
11
10
from Cookie import SimpleCookie
12
11
import os
12
+ from saml2 .profile import ecp
13
13
14
14
from saml2 import server
15
15
from saml2 import BINDING_HTTP_ARTIFACT
24
24
from saml2 .authn_context import PASSWORD
25
25
from saml2 .authn_context import UNSPECIFIED
26
26
from saml2 .authn_context import authn_context_class_ref
27
- from saml2 .extension import pefim
28
27
from saml2 .httputil import Response
29
28
from saml2 .httputil import NotFound
30
29
from saml2 .httputil import geturl
35
34
from saml2 .httputil import ServiceError
36
35
from saml2 .ident import Unknown
37
36
from saml2 .metadata import create_metadata_string
38
- from saml2 .s_utils import rndstr , exception_trace
37
+ from saml2 .s_utils import rndstr
38
+ from saml2 .s_utils import exception_trace
39
39
from saml2 .s_utils import UnknownPrincipal
40
40
from saml2 .s_utils import UnsupportedBinding
41
41
from saml2 .s_utils import PolicyError
42
- from saml2 .sigver import verify_redirect_signature , cert_from_instance , encrypt_cert_from_item
42
+ from saml2 .sigver import verify_redirect_signature
43
+ from saml2 .sigver import encrypt_cert_from_item
43
44
44
45
logger = logging .getLogger ("saml2.idp" )
45
46
@@ -239,6 +240,7 @@ def __init__(self, environ, start_response, user=None):
239
240
self .binding_out = None
240
241
self .destination = None
241
242
self .req_info = None
243
+ self .op_type = ""
242
244
243
245
def verify_request (self , query , binding ):
244
246
"""
@@ -258,10 +260,14 @@ def verify_request(self, query, binding):
258
260
_authn_req = self .req_info .message
259
261
logger .debug ("%s" % _authn_req )
260
262
261
- self .binding_out , self .destination = IDP .pick_binding (
262
- "assertion_consumer_service" ,
263
- bindings = self .response_bindings ,
264
- entity_id = _authn_req .issuer .text )
263
+ try :
264
+ self .binding_out , self .destination = IDP .pick_binding (
265
+ "assertion_consumer_service" ,
266
+ bindings = self .response_bindings ,
267
+ entity_id = _authn_req .issuer .text )
268
+ except Exception as err :
269
+ logger .error ("Couldn't find receiver endpoint: %s" % err )
270
+ raise
265
271
266
272
logger .debug ("Binding: %s, destination: %s" % (self .binding_out ,
267
273
self .destination ))
@@ -270,23 +276,31 @@ def verify_request(self, query, binding):
270
276
try :
271
277
resp_args = IDP .response_args (_authn_req )
272
278
_resp = None
273
- except UnknownPrincipal , excp :
279
+ except UnknownPrincipal as excp :
274
280
_resp = IDP .create_error_response (_authn_req .id ,
275
281
self .destination , excp )
276
- except UnsupportedBinding , excp :
282
+ except UnsupportedBinding as excp :
277
283
_resp = IDP .create_error_response (_authn_req .id ,
278
284
self .destination , excp )
279
285
280
286
return resp_args , _resp
281
287
282
288
def do (self , query , binding_in , relay_state = "" , encrypt_cert = None ):
289
+ """
290
+
291
+ :param query: The request
292
+ :param binding_in: Which binding was used when receiving the query
293
+ :param relay_state: The relay state provided by the SP
294
+ :param encrypt_cert: Cert to use for encryption
295
+ :return: A response
296
+ """
283
297
try :
284
298
resp_args , _resp = self .verify_request (query , binding_in )
285
- except UnknownPrincipal , excp :
299
+ except UnknownPrincipal as excp :
286
300
logger .error ("UnknownPrincipal: %s" % (excp ,))
287
301
resp = ServiceError ("UnknownPrincipal: %s" % (excp ,))
288
302
return resp (self .environ , self .start_response )
289
- except UnsupportedBinding , excp :
303
+ except UnsupportedBinding as excp :
290
304
logger .error ("UnsupportedBinding: %s" % (excp ,))
291
305
resp = ServiceError ("UnsupportedBinding: %s" % (excp ,))
292
306
return resp (self .environ , self .start_response )
@@ -299,19 +313,34 @@ def do(self, query, binding_in, relay_state="", encrypt_cert=None):
299
313
if REPOZE_ID_EQUIVALENT :
300
314
identity [REPOZE_ID_EQUIVALENT ] = self .user
301
315
try :
316
+ try :
317
+ metod = self .environ ["idp.authn_ref" ]
318
+ except KeyError :
319
+ pass
320
+ else :
321
+ resp_args ["authn" ] = metod
322
+
302
323
_resp = IDP .create_authn_response (
303
324
identity , userid = self .user ,
304
- authn = AUTHN_BROKER [ self . environ [ "idp.authn_ref" ]], encrypt_cert = encrypt_cert ,
325
+ encrypt_cert = encrypt_cert ,
305
326
** resp_args )
306
- except Exception , excp :
327
+ except Exception as excp :
307
328
logging .error (exception_trace (excp ))
308
329
resp = ServiceError ("Exception: %s" % (excp ,))
309
330
return resp (self .environ , self .start_response )
310
331
311
332
logger .info ("AuthNResponse: %s" % _resp )
333
+ if self .op_type == "ecp" :
334
+ kwargs = {"soap_headers" : [
335
+ ecp .Response (
336
+ assertion_consumer_service_url = self .destination )]}
337
+ else :
338
+ kwargs = {}
339
+
312
340
http_args = IDP .apply_binding (self .binding_out ,
313
341
"%s" % _resp , self .destination ,
314
- relay_state , response = True )
342
+ relay_state , response = True , ** kwargs )
343
+
315
344
logger .debug ("HTTPargs: %s" % http_args )
316
345
return self .response (self .binding_out , http_args )
317
346
@@ -412,6 +441,9 @@ def ecp(self):
412
441
if PASSWD [user ] != passwd :
413
442
resp = Unauthorized ()
414
443
self .user = user
444
+ self .environ [
445
+ "idp.authn_ref" ] = AUTHN_BROKER .get_authn_by_accr (
446
+ PASSWORD )
415
447
except ValueError :
416
448
resp = Unauthorized ()
417
449
else :
@@ -425,6 +457,7 @@ def ecp(self):
425
457
_dict = self .unpack_soap ()
426
458
self .response_bindings = [BINDING_PAOS ]
427
459
# Basic auth ?!
460
+ self .op_type = "ecp"
428
461
return self .operation (_dict , BINDING_SOAP )
429
462
430
463
# -----------------------------------------------------------------------------
@@ -542,7 +575,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None):
542
575
_ , body = request .split ("\n " )
543
576
logger .debug ("req: '%s'" % body )
544
577
req_info = IDP .parse_logout_request (body , binding )
545
- except Exception , exc :
578
+ except Exception as exc :
546
579
logger .error ("Bad request: %s" % exc )
547
580
resp = BadRequest ("%s" % exc )
548
581
return resp (self .environ , self .start_response )
@@ -559,7 +592,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None):
559
592
# remove the authentication
560
593
try :
561
594
IDP .session_db .remove_authn_statements (msg .name_id )
562
- except KeyError , exc :
595
+ except KeyError as exc :
563
596
logger .error ("ServiceError: %s" % exc )
564
597
resp = ServiceError ("%s" % exc )
565
598
return resp (self .environ , self .start_response )
@@ -568,7 +601,7 @@ def do(self, request, binding, relay_state="", encrypt_cert=None):
568
601
569
602
try :
570
603
hinfo = IDP .apply_binding (binding , "%s" % resp , "" , relay_state )
571
- except Exception , exc :
604
+ except Exception as exc :
572
605
logger .error ("ServiceError: %s" % exc )
573
606
resp = ServiceError ("%s" % exc )
574
607
return resp (self .environ , self .start_response )
0 commit comments