Example #1
0
 def _export_own_metadata(self):
     """recompute our own metadata."""
     from dm.saml2.pyxb import metadata
     ed = metadata.EntityDescriptor(
         entityID=self.entity_id,
         validUntil=utcnow() + self.metadata_validity,
     )
     ld = metadata.__dict__
     for r, p in self.roles.items():
         if r == "ap": continue  # for the moment
         i = self.unrestrictedTraverse(p)
         rd = ld[role2element[r]]()
         getattr(ed, rd.__class__.__name__[:-4]).append(rd)
         for c in (self.certificate, self.future_certificate):
             if c:
                 c = _make_absolute(c)
                 # build key_info
                 from pyxb.bundles.wssplat.ds import KeyInfo, X509Data
                 # this assumes the file to contain a (binary) X509v3 certificate
                 cert = open(c, "rb").read()
                 x509 = X509Data()
                 x509.X509Certificate = [cert]
                 key_info = KeyInfo()
                 key_info.X509Data = [x509]
                 rd.KeyDescriptor.append(
                     metadata.KeyDescriptor(key_info, use="signing"))
         if hasattr(rd, "NameIDFormat"):
             nifs = INameidFormatSupport(i)
             rd.NameIDFormat = nifs.supported
         # add role specific information -- we do not yet support all roles
         getattr(self, "gen_metadata_" + r)(i, rd)
     return ed.toxml()
    def _export_own_metadata(self):
        """recompute our own metadata."""
        from dm.saml2.pyxb import metadata

        ed = metadata.EntityDescriptor(entityID=self.entity_id, validUntil=utcnow() + self.metadata_validity)
        ld = metadata.__dict__
        for r, p in self.roles.items():
            if r == "ap":
                continue  # for the moment
            i = self.unrestrictedTraverse(p)
            rd = ld[role2element[r]]()
            getattr(ed, rd.__class__.__name__[:-4]).append(rd)
            for c in (self.certificate, self.future_certificate):
                if c:
                    c = _make_absolute(c)
                    # build key_info
                    from pyxb.bundles.wssplat.ds import KeyInfo, X509Data

                    # this assumes the file to contain a (binary) X509v3 certificate
                    cert = open(c, "rb").read()
                    x509 = X509Data()
                    x509.X509Certificate = [cert]
                    key_info = KeyInfo()
                    key_info.X509Data = [x509]
                    rd.KeyDescriptor.append(metadata.KeyDescriptor(key_info, use="signing"))
            if hasattr(rd, "NameIDFormat"):
                nifs = INameidFormatSupport(i)
                rd.NameIDFormat = nifs.supported
            # add role specific information -- we do not yet support all roles
            getattr(self, "gen_metadata_" + r)(i, rd)
        return ed.toxml()
Example #3
0
 def _make_authn_assertion(self, target, req, member):
     from dm.saml2.pyxb.assertion import SubjectType, AuthnStatement, \
          AuthnContext, AuthnContextClassRef
     ass = self.make_assertion()
     subject = self.subject_from_member(member, target, req)
     if not isinstance(subject, SubjectType): return subject  # an error
     # add `SubjectConfirmation` and `AudienceRestriction`
     #   as required by the `Web Browser SSO Profile`
     # We might want to put this into a mixin class as
     #   it is helpful for any use of the HTTP-Post binding.
     from dm.saml2.pyxb.assertion import \
          SubjectConfirmation, SubjectConfirmationData, \
          Conditions, AudienceRestriction, Audience
     target.resolve(self._get_authority(), req)
     subject.SubjectConfirmation.append(
         SubjectConfirmation(
             SubjectConfirmationData(
                 NotOnOrAfter=utcnow() + self.BROWSER_SSO_VALIDITY,
                 Recipient=target.url,
                 InResponseTo=req.ID,
             ),
             Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"))
     cs = ass.Conditions = Conditions()
     cs.AudienceRestriction.append(AudienceRestriction(Audience(
         target.eid)))
     ass.Subject = subject
     # do we need `Conditions`?
     ass.AuthnStatement.append(
         AuthnStatement(
             AuthnContext(AuthnContextClassRef(self.authn_context_class)),
             AuthnInstant=ass.IssueInstant,  # we cheet here
         ))
     return ass
 def is_valid(self, context=None):
   # according to 2.5.1.1 we should implement a three-value logic
   #  (invalid, valid, indeterminate) -- we fail to do so.
   now = utcnow()
   cv = self.NotBefore
   if cv is not None and now < as_utc(cv): return False
   cv = self.NotOnOrAfter
   if cv is not None and now >= as_utc(cv): return False
   for c in self.Condition:
     if not c.is_valid(context): return False
   for c in self.AudienceRestriction:
     if not c.is_valid(context): return False
   for c in self.OneTimeUse:
     if not c.is_valid(context): return False
   for c in self.ProxyRestriction: pass
   return True
 def is_valid(self, context=None):
     # according to 2.5.1.1 we should implement a three-value logic
     #  (invalid, valid, indeterminate) -- we fail to do so.
     now = utcnow()
     cv = self.NotBefore
     if cv is not None and now < as_utc(cv): return False
     cv = self.NotOnOrAfter
     if cv is not None and now >= as_utc(cv): return False
     for c in self.Condition:
         if not c.is_valid(context): return False
     for c in self.AudienceRestriction:
         if not c.is_valid(context): return False
     for c in self.OneTimeUse:
         if not c.is_valid(context): return False
     for c in self.ProxyRestriction:
         pass
     return True
Example #6
0
 def _process_assertion(self, ass, context):
     # ensure we know the issuer -- an exception results, if not
     eid = ass.Issuer.value()
     auth = self._get_authority()
     auth.metadata_by_id(eid)
     if not ass.verified_signature():
         raise SamlError("assertion %s was not signed by the issuer" %
                         ass.ID)
     if not ass.is_valid(context):
         raise SamlError("assertion %s is not valid" % ass.ID)
     if context.binding == "post":
         # check the `SubjectConfirmation` condition of the `Browser SSO profile`
         ok = False
         for sc in ass.Subject.SubjectConfirmation:
             scm = sc.Method
             if scm != "urn:oasis:names:tc:SAML:2.0:cm:bearer":
                 # we do not understand the method -- hope, we find one we understand
                 continue
             scd = sc.SubjectConfirmationData
             if scd is None: continue  # not valid
             if scd.NotOnOrAfter is None or utcnow() >= as_utc(
                     scd.NotOnOrAfter):
                 continue  # not valid
             if scd.Recipient != context.rsp.Destination:
                 continue  # not valid
             if scd.InResponseTo != context.rsp.InResponseTo:
                 continue  # not valid
             # XXX Jazkarta Note: NYU is on a private network, so we get an address
             # mismatch here. At the point at which we want to remove
             # client-specific customizations, we'll have to monkey patch this
             # method or find some other means of overriding this check:
             # if scd.Address and context.zrequest.getClientAddr() != scd.Address:
             #   continue # not valid
             ok = True
             break
         if not ok:
             raise SamlError(
                 "subject confirmation in assertion %s is invalid" % ass.ID)
     subject = ass.Subject.NameID
     for tag in ("Statement", "AuthnStatement", "AuthzDecisionStatement",
                 "AttributeStatement"):
         for s in getattr(ass, tag):
             # process statement -- "AttributeError", if we do not support its type
             getattr(self, "_process_" + tag)(subject, s)
    def _make_authn_assertion(self, target, req, member):
        from dm.saml2.pyxb.assertion import SubjectType, AuthnStatement, AuthnContext, AuthnContextClassRef

        ass = self.make_assertion()
        subject = self.subject_from_member(member, target, req)
        if not isinstance(subject, SubjectType):
            return subject  # an error
        # add `SubjectConfirmation` and `AudienceRestriction`
        #   as required by the `Web Browser SSO Profile`
        # We might want to put this into a mixin class as
        #   it is helpful for any use of the HTTP-Post binding.
        from dm.saml2.pyxb.assertion import (
            SubjectConfirmation,
            SubjectConfirmationData,
            Conditions,
            AudienceRestriction,
            Audience,
        )

        target.resolve(self._get_authority(), req)
        subject.SubjectConfirmation.append(
            SubjectConfirmation(
                SubjectConfirmationData(
                    NotOnOrAfter=utcnow() + self.BROWSER_SSO_VALIDITY, Recipient=target.url, InResponseTo=req.ID
                ),
                Method="urn:oasis:names:tc:SAML:2.0:cm:bearer",
            )
        )
        cs = ass.Conditions = Conditions()
        cs.AudienceRestriction.append(AudienceRestriction(Audience(target.eid)))
        ass.Subject = subject
        # do we need `Conditions`?
        ass.AuthnStatement.append(
            AuthnStatement(
                AuthnContext(AuthnContextClassRef(self.authn_context_class)),
                AuthnInstant=ass.IssueInstant,  # we cheet here
            )
        )
        return ass
 def _process_assertion(self, ass, context):
   # ensure we know the issuer -- an exception results, if not
   eid = ass.Issuer.value()
   auth = self._get_authority()
   auth.metadata_by_id(eid)
   if not ass.verified_signature():
     raise SamlError("assertion %s was not signed by the issuer" % ass.ID)
   if not ass.is_valid(context):
     raise SamlError("assertion %s is not valid" % ass.ID)
   if context.binding == "post":
     # check the `SubjectConfirmation` condition of the `Browser SSO profile`
     ok = False
     for sc in ass.Subject.SubjectConfirmation:
       scm = sc.Method
       if scm != "urn:oasis:names:tc:SAML:2.0:cm:bearer":
         # we do not understand the method -- hope, we find one we understand
         continue
       scd = sc.SubjectConfirmationData
       if scd is None: continue # not valid
       if scd.NotOnOrAfter is None or utcnow() >= as_utc(scd.NotOnOrAfter):
         continue # not valid
       if scd.Recipient != context.rsp.Destination:
         continue # not valid
       if scd.InResponseTo != context.rsp.InResponseTo:
         continue # not valid
       if scd.Address and context.zrequest.getClientAddr() != scd.Address:
         continue # not valid
       ok = True
       break
     if not ok:
       raise SamlError("subject confirmation in assertion %s is invalid" % ass.ID)
   subject = ass.Subject.NameID
   for tag in ("Statement", "AuthnStatement", "AuthzDecisionStatement", "AttributeStatement"):
     for s in getattr(ass, tag):
       # process statement -- "AttributeError", if we do not support its type
       getattr(self, "_process_" + tag)(subject, s)
Example #9
0
 def get_authentication_session(self, request):
     info = self._get_cookie(request, self.session_cookie_name)
     if info is None: return
     if info["valid_until"] is not None:
         if utcnow() >= info["valid_until"]: return  # no longer valid
     return info
 def __init__(self, *args, **kw):
     if 'Version' not in kw: kw['Version'] = '2.0'
     # Note: an id must start with a char
     if 'ID' not in kw: kw['ID'] = '_' + uuid()
     if 'IssueInstant' not in kw: kw['IssueInstant'] = utcnow()
     super(_StandardSaml2Initialization, self).__init__(*args, **kw)
 def get_authentication_session(self, request):
   info = self._get_cookie(request, self.session_cookie_name)
   if info is None: return
   if info["valid_until"] is not None:
     if utcnow() >= info["valid_until"]: return # no longer valid
   return info
 def __init__(self, *args, **kw):
   if 'Version' not in kw: kw['Version'] = '2.0'
   # Note: an id must start with a char
   if 'ID' not in kw: kw['ID'] = '_' + uuid()
   if 'IssueInstant' not in kw: kw['IssueInstant'] = utcnow()
   super(_StandardSaml2Initialization, self).__init__(*args, **kw)