Giter VIP home page Giter VIP logo

pysaml2's Introduction

PySAML2 - SAML2 for Python

Version Supported Python versions Total downloads Weekly downloads License

PySAML2 is a pure python implementation of SAML Version 2 Standard. It contains all necessary pieces for building a SAML2 service provider or an identity provider. The distribution contains examples of both. Originally written to work in a WSGI environment there are extensions that allow you to use it with other frameworks.

Website: https://idpy.org/

Documentation: https://pysaml2.readthedocs.io/

Contribution guidelines: CONTRIBUTING.md

Security policies: SECURITY.md

Source code: https://github.com/IdentityPython/pysaml2/

Developer guidelines: DEVELOPERS.md

PyPI project: https://pypi.org/project/pysaml2/

License: LICENSE

Specifications

Retrieved from https://wiki.oasis-open.org/security/FrontPage

SAML V2.0 Standard

Profiles and extensions

Committee Specifications

Installation

You can install PySAML2 through pip:

pip install pysaml2

External dependencies

PySAML2 works with the xmlsec binary. Notice that support for xmlsec 1 1.3 was added with v7.4.2.

xmlsec should be readily available in most Linux distributions:

$ apt-get install xmlsec1
$ dnf install xmlsec1-openssl
$ yum install xmlsec1-openssl
$ pacman -S xmlsec
...

and on MacOS through homebrew

$ brew install libxmlsec1

Changelog

See the CHANGELOG to learn about the latest developments.

Contributing

We've set up a separate document for our contribution guidelines.

Community

IdentityPython is a community around a collection of libraries and tools to manage identity related concepts with Python code. You can interact with the community though the mailing list or on the Slack workspace (invitation).

Development

We've set up a separate document for developers.

Releasing

We've set up a separate document for our release process.

Pre-commit

(TODO)

pysaml2's People

Contributors

akx avatar arucard21 avatar ashimaathri avatar baijum avatar c00kiemon5ter avatar dallerbarn avatar dfeinzeig avatar fredrikt avatar hatoho avatar hlein avatar jdufresne avatar jkakavas avatar johanlundberg avatar knaperek avatar lorenzogil avatar maxbes avatar nsklikas avatar patrickbr avatar paulftw avatar peppelinux avatar rectalogic avatar rhoerbe avatar rohe avatar shabda avatar sigmunau avatar skoranda avatar spaceone avatar spamaps avatar tpazderka avatar vladimir-mencl-eresearch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pysaml2's Issues

Test 40_sigver failing

test_40_sigver is failing with the following message:
IOError: [Errno 2] No such file or directory: '.../pysaml2/tests/idp_example.xml'

The file is missing in the repository.

saml2/server.py requires python-memcached

Is python-memcached a requirement? Right now I think it is.

But as it is not the default cache method the import should be somehow wrapped depending on the config.

Are you open for this change? I can probably send a patch.

Let me know.

_sso_location sometimes returns exceptions instead of raising them

The _sso_location method in Saml2Client (which is called by Saml2Client.authenticate) creates a IdpUnspecified exception in three places, but in two of those places, it returns the exception instead of raising it.

I tried changing it so that it raises the exception in all three cases, but that causes a test to fail in test_63_ecp.

So either the test is misconfigured and wasn't noticing because the exception was getting lost, or everything is working as expected. If that's the case, I'd suggest returning something other than an exception or otherwise indicating that this isn't a fatal error.

If the test is misconfigured and should have been failing, it should probably be updated so that it's doing more evaluation of the return value. It seems bad that an exception class could be folded into a saml object without the test noticing.

KeyError in _get_rememberer()

While trying to use pysaml2 in a pyramid application together with repoze.who and pyramid_whoauth, I ran into some unexpected problems. I am creating a WhoAuthenticationPolicy like this:

api_factory = make_api_factory_with_config(global_config, "who.ini")
authn_policy = auth.WhoAuthenticationPolicy(api_factory)
config = Configurator(settings=settings, session_factory=session_factory, root_factory='wkp.Root')
config.include("pyramid_whoauth")
config.set_authentication_policy(authn_policy)

However, as soon as I am trying to request a view with access restrictions, pysaml2 fails fetching the key 'repoze.who.plugins' from the environ dict. This key is indeed nonexistent. The KeyError happens in self._get_rememberer(environ).

I am strongly suspecting some compatibility problems between the current version of repoze.who and pysaml2 1.0. Is there any way to get pysaml2 to work with pyramid_who or pyramid_whoauth? If not, what is the preferred way to use pysaml2 with pyramid?

Thanks!

Support for repoze.who 2

The README states that the latest version of repoze.who should be used, whereas setup.py pins repoze.who == 1.0.18.

Does pysaml work with repoze.who >= 2? If so, this ticket is about documenting this and lifting the requirement in setup.py to repoze.who >= 1.0.18 ; if not, this ticket is about adding support for it.

Thanks!

Implementing on GAE

Hello, I have a question.

Has anyone successfully implemented an IDP using library in Google App Engine (GAE)?

I needed to change some references to imports like memcache since I am in a sandbox.
Just wondering what else was required and/or if there is sample code.

Thanks

New dependencey on dateutil

Starting idp_testdrv.py after a recent pull results in "tImportError: No module named dateutil.parser".
It can easily be fixed with:
pip install python-dateutil

python-dateutil should be added to setup.py

Redirect binding fails to set SigAlg and Signature parameters in the URL

These two parameters are never set anywhere: https://github.com/rohe/pysaml2/blob/master/src/saml2/pack.py#L80

When working with an IdP like PingFederate, the requests always fail because PingFederate cannot find SigAlg and Signature parameters in the URL.

See line 594 of the spec: http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf

Excerpt:

If the underlying SAML protocol message is signed with an XML signature [XMLSig], the URL-encoded
form of the message MUST be signed as follows:

  1. The signature algorithm identifier MUST be included as an additional query string parameter,
    named SigAlg. The value of this parameter MUST be a URI that identifies the algorithm used to
    sign the URL-encoded SAML protocol message, specified according to [XMLSig] or whatever
    specification governs the algorithm
    ...

Trying to implement BASIC auth on SP.

I was thinking this should be possible. Implement BASIC authentication to be accepted on the SP and pass the credentials to the ECP endpoint on the IDP to establish login.
That way I don't need to configure a separate LDAP access in repoze.who on the SP side.
Do you think that's possible?

httplib2 ssl certificate verification issue when retrieving remote metadata

httplib2, by default, uses it's own certificate authority for verifying ssl certificates. If the certificate used, in my case a self-signed cert used while developing, is not verifiable by that certificate authority, you get an error.

Error received from httplib2:

SSLHandshakeError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Trace back puts the error here:

File "/home/phoenix/phoenix-deploy/lib/python2.7/site-packages/saml2/metadata.py", line 478, in import_external_metadata
(response, content) = self.http.request(url)

Solution would seem to be the same as is being done in the one other place that httplib2 is being used for making requests internally which is in soap.py. Here HttpClient is calling httplib2.Http() with the options for an alternate ca_certs file or disable_ssl_certificate_validation.

The call for retrieving remote metadata should include the same options.

Example appears broken

Trying to run the example via run.sh I have run into various problems.

I needed to do this

diff --git a/example/idp/idp.py b/example/idp/idp.py
index a44a125..82d6981 100755
--- a/example/idp/idp.py
+++ b/example/idp/idp.py
@@ -107,7 +107,7 @@ def sso(environ, start_response, user, logger):
                 "<title>SAML 2.0 POST</title>",
                 "</head><body>",
                 FORM_SPEC % (req_info["consumer_url"],
-                             base64.b64encode("".join(authn_resp)), "/"),
+                             base64.b64encode(str(authn_resp)), "/"),
                 """<script type="text/javascript" language="JavaScript">""",
                 "     document.myform.submit();",
                 """</script>""",

to get anywhere

then in example/sp/sp.py line 101
tmp = client.saml_client.global_logout(subject_id, return_to=target)

return_to parameter is not valid. It seems you removed this yesterday.

I've got past that but am now getting problems with the logging out causing a

File "/home/toby/okfn/pyenv/src/pysaml2/src/saml2/request.py", line 84, in _verify
    raise OtherError("Not destined for me!")

It would be great to have the example working again as I will need to use the idp part of it for testing the integration of saml2 with my application as I have no real idp to work with at present

Thanks

invalid @WantAuthnRequestsOnlyWithValidCert in metadata

make_metadata generates this snippet:

<ns0:EntityDescriptor entityID="https://idp.example.org/idp.xml" validUntil="2014-04-22T14:10:29Z" 
                      xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata">
    <ns0:IDPSSODescriptor WantAuthnRequestsOnlyWithValidCert="False" WantAuthnRequestsSigned="True"
                          protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

WantAuthnRequestsOnlyWithValidCert is not in a valid namespace.

MD validation fails on date type

Starting the example IDP results in the message:
saml2.mdstore - ERROR - Class 'EntitiesDescriptor' instance: Wrong type of value '2014-04-25T13:30:02' on attribute 'valid_until' expected it to be dateTime

The input MD is XML schema-valid, and the value looks good.

Removing valid_until "fixes" the problem.

Cutting a new release?

I've landed all of my patches here and for [djangosaml2|https://bitbucket.org/lgs/djangosaml2]. Would it be possible to get a release sometime soon?

how do I add support for the SAMLart artifacts?

For some reasons my shibboleth IdP refuses to accept any assertion_consumer_service except for the HTTP artifact.
After modifying the example sp_conf to contain
"assertion_consumer_service": [(BASE, BINDING_HTTP_ARTIFACT)],
I found out that repoze plugin simply ignores the SAMLart URL parameter.
What should I do to add support for this SAML2 feature?

Please explain what attribute_map_dir maps are for?

What are the fro attributes and what are the to attributes?

In basic.py you have:

MAP = {
    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
    "fro": {
        'urn:mace:dir:attribute-def:aRecord': 'aRecord',
        ...
    }
}

Is the left side a SAML attribute name and the right side a Python dict key? or they are both in the SAML realm?

I am setting up an IdP which needs to be compatible with assertions in the form:

<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="FirstName">
    <saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">SAML</saml:AttributeValue>
</saml:Attribute>

I'm guessing my map would be:

MAP = {
    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
    "fro": {
        'FirstName': 'FirstName',
        ...
    }
}

Do I even need a map?

AuthnRequest can only use a ProtocolBinding of HTTP-POST or HTTP-Artifact

I was running into a problem getting pysaml2 to talk to a Shibboleth IdP, and I was running into a problem getting an AuthnRequest to work when I listed a redirect

<ns0:AuthnRequest xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"
                  xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion"
                  AssertionConsumerServiceURL="http://localhost:8087/acs/redirect"
                  Destination="https://localhost:8443/idp/profile/SAML2/Redirect/SSO"
                  ID="id-4dd9bccfd5af98c5ddb922109639153b"
                  IssueInstant="2014-11-03T23:37:13Z"
                  ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
                  Version="2.0"
                  >
    <ns1:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">erickt/sp.xml</ns1:Issuer>
    <ns0:NameIDPolicy AllowCreate="false"
                      Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
                      />
</ns0:AuthnRequest>

Shibboleth would reply with this error:

 Error Message: No peer endpoint available to which to send SAML response

In the Shibboleth logs, it mentions:

15:37:32.549 - DEBUG [org.opensaml.saml2.binding.AuthnResponseEndpointSelector:99] - Filtering peer endpoints.  Supported peer endpoint bindings: [urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign, urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST, urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact]
15:37:32.549 - DEBUG [org.opensaml.saml2.binding.AuthnResponseEndpointSelector:114] - Removing endpoint http://localhost:8087/acs/redirect because its binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect is not supported
15:37:32.550 - ERROR [edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler:447] - No return endpoint available for relying party erickt/sp.xml

However, if I swap the order of the "assertion_consumer_service" in examples/sp-wgsi/sp_conf.py, it works:

...
                "assertion_consumer_service": [
                    ("%s/acs/post" % BASE, BINDING_HTTP_POST),
                    ("%s/acs/redirect" % BASE, BINDING_HTTP_REDIRECT),
                ],
...

It took a bit to track down, but I believe the problem is that according to the SAML V2.0 spec, in section 4.1.2 part 5, AuthnRequest replies cannot use HTTP-Redirect:

421 In step 5, the identity provider issues a <Response> message to be delivered by the user agent
422 to the service provider. Either the HTTP POST, or HTTP Artifact binding can be used to transfer
423 the message to the service provider through the user agent. The message may indicate an error,
424 or will include (at least) an authentication assertion. The HTTP Redirect binding MUST NOT be
425 used, as the response will typically exceed the URL length permitted by most user agents.

If I'm reading the spec correctly, that means that it should be an error to use AssertionConsumerService with the binding urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect. Is this correct?

MetadataStore._providers() uses a hardcoded string instead of parameter

MetadataStore._providers() uses a hardcoded string ("spsso_descriptor") instead of the descriptor parameter. As a result, calling identity_providers() or attribute_authorities() will always return service_providers.

I have a simple fix, and can create a pull request if you want me to.

--- a/src/saml2/mdstore.py
+++ b/src/saml2/mdstore.py
@@ -808,7 +808,7 @@ class MetadataStore(object):
         res = []
         for md in self.metadata.values():
             for ent_id, ent_desc in md.items():
-                if "spsso_descriptor" in ent_desc:
+                if descriptor in ent_desc:
                     res.append(ent_id)
         return res

Getting error dateutil.parse not found

I was using commit id b1ab606
but now using master I am getting

Reading newrelic.ini at /u1/deploy/3007/prototype10/../newrelic.ini
Traceback (most recent call last):
  File "./server.py", line 43, in <module>
    from saml2.metadata import create_metadata_string
  File "/u1/private/3007/prototype10/env/local/lib/python2.7/site-packages/saml2/metadata.py", line 2, in <module>
    from saml2.sigver import security_context
  File "/u1/private/3007/prototype10/env/local/lib/python2.7/site-packages/saml2/sigver.py", line 35, in <module>
    from saml2.cert import OpenSSLWrapper
  File "/u1/private/3007/prototype10/env/local/lib/python2.7/site-packages/saml2/cert.py", line 5, in <module>
    import dateutil.parser
ImportError: No module named dateutil.parser

Looks like python-dateutil and pyOpenSSL are not in the dependency list.
In addition I am gettin an error during logout...

2014-03-06 10:52:52,773 saml2.idp:ERROR Bad request: correctly_signed_logout_request() got an unexpected keyword argument 'only_valid_cert'

Missing tag in repo for v1.1.0

The latest version of the code that is packaged to pypi is 1.1.0. There is no tag for that version in this github repo.

Attribute converters ignore attrname-format:unspecified

A customer's identity provider sends me assertions with
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified

As a result, client.response(...).session_info().get('ava', {}) returns an empty list.

Firstly, is this expected behaviour?
For the AttributeStatement below I'd expect to see ava equal to

{
  'user_id': ['bob'],
  'NameID': ['bobsnameagain'],
}

But instead ava is [].
I have written a custom attribute converter that returns the attribute data as is. However, this feels more like a workaround. I this should work "out of the box", shouldn't it?

Secondly, to_local in the attribute_converter.py uses a fallback value [].
That is inconsistent with dictionaries returned by successful attribute converters.

Example statement to reproduce the issue:
<?xml version='1.0' encoding='UTF-8'?>
<ns0:AttributeStatement xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ns0:Attribute Name="user_id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <ns0:AttributeValue xsi:type="xs:string">bob</ns0:AttributeValue>
    </ns0:Attribute>
    <ns0:Attribute Name="NameID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <ns0:AttributeValue xsi:type="xs:string">bobsnameagain</ns0:AttributeValue>
    </ns0:Attribute>
</ns0:AttributeStatement>

refactor "UnknownPrincipal" exception to "UnknownSystemEntity"

A principal is a user, not an entity in SAML. The UnknownPrincipal exception in mdstore.py should be renamed as suggested in the title to avoid confusion.
Unfortunately the OASIS SAML glossary is using the X-811 definition of principal, but contradicts itself otherwise by redefining the term implicitly in other definitions such as Account, Affiliation, IDP, Persistent Pseudonym, etc.

Version 1.1.0 on PyPI links to docs for version 0.4.3

The "Package Documentation" link on the PyPI page for version 1.1.0 (https://pypi.python.org/pypi/pysaml2/1.1.0) links to documentation for version 0.4.3 (http://pythonhosted.org//pysaml2/).

It might be easiest to switch to ReadTheDocs for documentation hosting (see #75) - they can host multiple versions of the docs simultaneously, with a version-picker UI, and will build all versions automatically, based on git tags, triggered by a github push hook.

The to_local_name function has inconsistent return values

This function takes a string value representing a local attribute name, and a name format. If it can find name mapping for the attribute in the specified name format, it returns an Attribute object for it. If it can't, it just returns the original attribute name.

The problem is that the returned value is assumed to be an instance of Attribute. I think the bigger problem is that this seems to be masking an error. It seems like the right thing to do here is just raise an exception.

config.py IdPConfig authz_services method is broken

This is the error I'm getting:

File "/opt/kavi/service/web/ve/lib/python2.7/site-packages/pysaml2-0.4.2-py2.7.egg/saml2/config.py", line 459, in authz_services
return self.metadata.authz_services(entity_id, "pdp",
AttributeError: 'MetaData' object has no attribute 'authz_services'

Think this is supposed to be "authz_service_endpoints".

XML metadata output does not include xmlns attributes

I have my own simplified code (based on the included make_metadata.py) for generating the XML metadata for my SP:

    from saml2.metadata import entity_descriptor
    from saml2.validate import valid_instance

    from .conf import get_config

    nspair = {
        'xs': 'http://www.w3.org/2001/XMLSchema',
        'md': 'urn:oasis:names:tc:SAML:2.0:metadata',
        'ds': 'http://www.w3.org/2000/09/xmldsig#',
    }
    cnf = get_config()
    ed = entity_descriptor(cnf)

    valid_instance(ed)
    xml = ed.to_string(nspair)

This works fine, except that the output xml does not have any xmlns:* attributes on the root EntityDescriptor node. The SimpleSAMLphp metadata parser (which I have to interoperate with) chokes on the XML if it does not have these attributes.

To be clear, pysaml2 is giving me this root node:

<md:EntityDescriptor entityID="myEntityID">

But simpleSAMLphp only parses the metadata if I give it this root node:

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="myEntityID">

Is there some way to convince pysaml2 to include these namespace definitions? Is it a bug that it does not?

Attribute conversion is confusing me

In my application I would like the IDP to send the DN and the DNs for all groups I am a member of to the SP. This seems to work with "member" for the group memberships but I can't figure out how to send the DN of the user. Is there something I am overlooking?

[Question] Using pysaml2 to authenticate users against an existing Service Provider

Hi,

As in the project's description, pysaml2 contains all necessary pieces for building a SAML2 service provider or an identity provider. And, after a while searching in the Internet, I only see people using pysaml2 to build saml sp or idp.

My question is: is there any good example show how to use pysaml2 to create an authentication backend for Django to authenticate users against an existing SP (and an existing Idp, of-course). Is it possible, anyway?

Thanks,

Trinh

Don't mask xmlsec1 execution errors

If xmlsec1 terminates with nonzero exit code, CryptoBackendXmlSec1._run_xmlsec() should raise an exception.

(Try debugging an ssl key file permission problem if _run_xmlsec returns an empty string, and you think it's the web server's error.)

parse_authn_requ should not run xmlsec to verify signature for redirect binding

xmlsec should not be invoked to redirect binding.

_loads in (saml2.request), does not pass on the binding on to (saml2.sigver) correctly_signed_message. Somewhere down the path the distinction between xml-dsig and SAML-redirect-binding signature is lost. As a consequence xmlsec is run; if no signature is required the xmlsec error is ignored.

slo error : Duplicate headers received from server

Hi Roland,

I've been getting issues with getting the example/sp to work without modifications.

currently sign-on works but on clicking on the logout link, the sp returns with a "Duplicate headers received from server" error

Tested on google chrome.

POST binding not passed through

(I also filed this bug on launchpad... not sure where to file these; apologies in advance)

https://github.com/rohe/pysaml2/blob/master/src/saml2/client.py#L388

Shouldn't binding be passed in here? If I use an HTTP POST binding,
and I pass this into the caller, it is not passed in HERE, and thus we
look for an HTTP REDIRECT binding (which my particular metadata I'm
testing with doesn't have).

i.e.

    location = self._sso_location(entityid)

should be

    location = self._sso_location(entityid, binding)

Compatibility problem with Microsoft's ADFS, possible solutions?

Hi,

we are still working on an implemenation of a Pyramid-based SAML SP via pysaml2. Our IdP uses MS-ADFS. Apparantly, ADFS is not entirely faithful to the SAML specification. The attribute values specified in the token are missing the nameFormat XML-attribute. Example:

<Attribute Name="http://schemas.xmlsoap.org/claims/commonName">
    <AttributeValue>testtest</AttributeValue>
</Attribute> 

pysaml2 won't parse attributes without a specified nameFormat. We fixed the problem by falling back to urn:oasis:names:tc:SAML:2.0:attrname-format:uri if the nameFormat is missing. This is done by initializing the member name_format in the class AttributeType_ with NAME_FORMAT_URI by default (see commit geops@1fce6d1).

Is this a legitimate way to handle the problem of ADFS compatibility or do you think it could cause problems? If so, what do you think would be the preferred way to provide an ADFS compatibility mode?

Thanks,
patrick

login_url assembled wrong

https://github.com/rohe/pysaml2/blob/master/src/saml2/binding.py#L99

When a url already has parameters, the encoded saml query is appended with another '?', when it should have been appended as another '&' instead.

A fix we used is:
saml2/binding.py
29d28
< import urlparse
100,101c99
<     glue_char = "&" if urlparse.urlparse(location).query else "?"
<     login_url = glue_char.join([location, urllib.urlencode(args)])


    login_url = "?".join([location, urllib.urlencode(args)])

Unused variables in Entity._parse_response leading to bug in LogoutResponse?

I'm porting djangosaml2 over to pysaml2 2.1.0, and I think I found a bug in how Entity._parse_response handles LogoutResponses on this djangosaml2 line. It's resulting in this exception:

Traceback (most recent call last):
  File "/Users/erickt/projects/django/djangosaml2/djangosaml2/tests/__init__.py", line 340, in test_logout_service_local
    'SAMLResponse': deflate_and_base64_encode(saml_response),
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/django/test/client.py", line 439, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/django/test/client.py", line 244, in get
    return self.request(**r)
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/django/core/handlers/base.py", line 109, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/Users/erickt/projects/django/djangosaml2/djangosaml2/views.py", line 271, in logout_service
    BINDING_HTTP_REDIRECT)
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/saml2/entity.py", line 932, in parse_logout_request_response
    "single_logout_service", binding)
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/saml2/entity.py", line 919, in _parse_response
    response = response.verify(key_file)
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/saml2/response.py", line 396, in verify
    return self._verify()
  File "/Users/erickt/virtualenvs/djangosaml2/lib/python2.7/site-packages/saml2/response.py", line 382, in _verify
    self.response.destination not in self.return_addrs:
TypeError: argument of type 'NoneType' is not iterable

I think this may be stemming from two unused variables in the Entity._parse_response method. The first is asynchop on line 869, the second is return_addrs on line 879:

...
        if self.config.accepted_time_diff:
            kwargs["timeslack"] = self.config.accepted_time_diff

        if "asynchop" not in kwargs:
            if binding in [BINDING_SOAP, BINDING_PAOS]:
                asynchop = False
            else:
                asynchop = True

        if xmlstr:
            if "return_addrs" not in kwargs:
                if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]:
                    try:
                        # expected return address
                        return_addrs = self.config.endpoint(
                            service, binding=binding)
                    except Exception:
                        logger.info("Not supposed to handle this!")
                        return None

            try:
                response = response_cls(self.sec, **kwargs)
            except Exception, exc:
                logger.info("%s" % exc)
                raise
...

Should this instead be:

        if "asynchop" not in kwargs:
            if binding in [BINDING_SOAP, BINDING_PAOS]:
                kwargs["asynchop"] = False
            else:
                kwargs["asynchop"] = True

        if xmlstr:
            if "return_addrs" not in kwargs:
                if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]:
                    try:
                        # expected return address
                        kwargs["return_addrs"] = self.config.endpoint(
                            service, binding=binding)
                    except Exception:
                        logger.info("Not supposed to handle this!")
                        return None

            try:
                response = response_cls(self.sec, **kwargs)
            except Exception, exc:
                logger.info("%s" % exc)
                raise

?

Dependency issue with M2Crypto

M2Crypto (0.17 up to 0.21) has build issues on Fedora/RHEL/CentOS platforms. The reason seems to be that RH removed EC support from OpenSSL, and M2Crypto/SWIG cannot deal with the modified openssl header files.
The proper way would be to install the OS package for M2Crypto. So 'yum m2crypto' properly installs m2crypto-0.20.2-9.el6.x86_64.

However, pysaml2 (from git) ignores this package and installs M2Crypto-0.21.1. As pip does not know about the platform issues, swig will fail with "This openssl-devel package does not work your architecture?". "uname -m" yields x86_64, but somehow swig seems to be unable to select the proper opensslconf-x86_64.h.

In addition, m2crypto does not resolve the dependencies for swig and openssl-devel, so this must be resolved manually.

Is there an essetial dependency between pysaml2 and M2Crypto-0.21? If yes, can the install process be fixed?

config.py IdPConfig assertion_consumer_services method is broken

Here is the error I'm receiving:

File "/opt/kavi/service/web/ve/lib/python2.7/site-packages/pysaml2-0.4.2-py2.7.egg/saml2/config.py", line 454, in assertion_consumer_services
return [s[binding] for s in acs]
TypeError: string indices must be integers, not NoneType

acs is a dictionary returned from what appears to be a deprecated method on the metadata object "sp_services".

I've duplicated the issue with the latest pysaml2 code as well.

Changing the line to "return acs.values()" results in the expected list.

The configuration option 'valid_for' is not used

In the documentation (/doc/howto/config.rst) it says:

valid_for

How many hours this configuration is expected to be accurate.:

"valid_for": 24

This of course is only used by make_metadata.py. The server will not stop working when this amount of time has elapsed :-).

But in the make_metadata.py script this parameter is not read from the config file. It is read from a command line option.

I suggest we:

A) Remove that option from the documentation or
B) Use the option from the config file as a default value overridable by the command line switch. Or even better, remove the 'valid_for' parameter from the saml2.metadata.entity_descriptor function and read it from the config parameter that it is already receiving.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.