Ejemplo n.º 1
0
    def __init__(self, idp_conf, logger, conf, publicKey, privateKey, metadataList):
        """
        Constructor.
        Initiates the class.
        :param logger: Logger to be used when something needs to be logged.
        :param conf: idp_proxy_conf see IdpProxy/conig/idp_proxy_conf.example.py
        :param key: A RSA key to be used for encryption.
        :param metadataList: A list of metadata files.
            [{"local": ["swamid-1.0.xml"]}, {"local": ["sp.xml"]}]
        :raise:
        """
        if (logger is None) or (conf is None) or (publicKey is None)or (privateKey is None):
            raise ValueError(
                "A new instance must include a value for logger, conf and key.")
        #Public key to be used for encryption.
        self.publicKey = publicKey
        self.privateKey = privateKey
        #Used for presentation of mako files.
        self.lookup = TemplateLookup(
            directories=[MetadataGeneration.CONST_STATIC_MAKO + 'templates',
                         MetadataGeneration.CONST_STATIC_MAKO + 'htdocs'],
            module_directory='modules',
            input_encoding='utf-8',
            output_encoding='utf-8')
        #The logger.
        self.logger = logger
        #A list of all social services used by this IdPproxy.
        self.socialServiceKeyList = []
        #A list of all service providers used by this sp.
        self.spKeyList = []
        for key in conf:
            self.socialServiceKeyList.append(conf[key]["name"])

        try:
            xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
        except:
            try:
                xmlsec_path = get_xmlsec_binary(["/usr/local/bin"])
            except:
                self.logger.info('Xmlsec must be installed! Tries /usr/bin/xmlsec1.')
                xmlsec_path = '/usr/bin/xmlsec1'

        self.xmlsec_path = xmlsec_path

        config = Config()
        config.disable_ssl_certificate_validation = True
        config.key_file = idp_conf["key_file"]
        config.cert_file = idp_conf["cert_file"]
        config.xmlsec_binary = idp_conf["xmlsec_binary"]
        config.debug = idp_conf["debug"]

        for metadata in metadataList:
            mds = MetadataStore(MetadataGeneration.CONST_ONTS.values(),
                                MetadataGeneration.CONST_ATTRCONV, config)
            mds.imp(metadata)
            for entityId in mds.keys():
                self.spKeyList.append(entityId)
Ejemplo n.º 2
0
def test_metadata_file():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(list(ONTS.values()), ATTRCONV, sec_config, disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["8"])
    print((len(list(mds.keys()))))
    assert len(list(mds.keys())) == 560
Ejemplo n.º 3
0
    def load(self, cnf, metadata_construction=False):
        """ The base load method, loads the configuration

        :param cnf: The configuration as a dictionary
        :param metadata_construction: Is this only to be able to construct
            metadata. If so some things can be left out.
        :return: The Configuration instance
        """
        for arg in COMMON_ARGS:
            try:
                self._attr[""][arg] = cnf[arg]
            except KeyError:
                pass

        if "service" in cnf:
            for typ in ["aa", "idp", "sp", "pdp"]:
                try:
                    self.load_special(cnf["service"][typ], typ,
                                    metadata_construction=metadata_construction)

                except KeyError:
                    pass

        if not metadata_construction:
            if "xmlsec_binary" not in self._attr[""]:
                self._attr[""]["xmlsec_binary"] = get_xmlsec_binary()
            # verify that xmlsec is where it's supposed to be
            if not os.access(self._attr[""]["xmlsec_binary"], os.F_OK):
                raise Exception("xmlsec binary not in '%s' !" % (
                                            self._attr[""]["xmlsec_binary"]))

        self.load_complex(cnf, metadata_construction=metadata_construction)
        self.context = self.def_context

        return self
Ejemplo n.º 4
0
def test_metadata_file():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["8"])
    print(len(mds.keys()))
    assert len(mds.keys()) == 560
Ejemplo n.º 5
0
def test_load_local_dir():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["9"])
    print mds
    assert len(mds) == 3  # Three sources
    assert len(mds.keys()) == 4  # number of idps
Ejemplo n.º 6
0
Archivo: conf.py Proyecto: Terradue/hue
def xmlsec():
  """
  xmlsec path
  """
  if get_xmlsec_binary:
    return get_xmlsec_binary()
  else:
    return '/usr/local/bin/xmlsec1'
Ejemplo n.º 7
0
def test_load_external():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["10"])
    print(mds)
    assert len(mds) == 1  # One source
    assert len(mds.keys()) > 1  # number of idps
Ejemplo n.º 8
0
def test_mdx_certs():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    http = HTTPBase(verify=False, ca_bundle=None)

    mdx = MetaDataMDX(quote_plus, ONTS.values(), ATTRCONV,
                      "http://pyff-test.nordu.net", sec_config, None, http)
    foo = mdx.certs("https://idp.umu.se/saml2/idp/metadata.php", "idpsso")

    assert len(foo) == 1
Ejemplo n.º 9
0
def test_load_extern_incommon():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["10"])
    print(mds)
    assert mds
    assert len(mds.keys())
Ejemplo n.º 10
0
def test_mdx_certs():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    http = HTTPBase(verify=False, ca_bundle=None)

    mdx = MetaDataMDX(ONTS.values(), ATTRCONV, "http://pyff-test.nordu.net",
                      sec_config, None, http)
    foo = mdx.certs("https://idp.umu.se/saml2/idp/metadata.php", "idpsso")

    assert len(foo) == 1
Ejemplo n.º 11
0
def test_load_external():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["10"])
    print(mds)
    assert len(mds) == 1  # One source
    assert len(mds.keys()) > 1  # number of idps
Ejemplo n.º 12
0
def test_load_local_dir():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["9"])
    print(mds)
    assert len(mds) == 3  # Three sources
    assert len(mds.keys()) == 4  # number of idps
Ejemplo n.º 13
0
def test_load_extern_incommon():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ATTRCONV,
                        sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["10"])
    print(mds)
    assert mds
    assert len(mds.keys())
Ejemplo n.º 14
0
def test_signed_metadata_proper_str_bytes_handling():
    sp_conf_2 = sp_conf.copy()
    sp_conf_2['key_file'] = full_path("test.key")
    sp_conf_2['cert_file'] = full_path("inc-md-cert.pem")
    # requires xmlsec binaries per https://pysaml2.readthedocs.io/en/latest/examples/sp.html
    sp_conf_2['xmlsec_binary'] = sigver.get_xmlsec_binary(["/opt/local/bin"])
    cnf = SPConfig().load(sp_conf_2, metadata_construction=True)

    # This will raise TypeError if string/bytes handling is not correct
    sp_metadata = create_metadata_string('', config=cnf, sign=True)
Ejemplo n.º 15
0
def test_mdx_service():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    http = HTTPBase(verify=False, ca_bundle=None)

    mdx = MetaDataMDX(quote_plus, ONTS.values(), ATTRCONV,
                      "http://pyff-test.nordu.net", sec_config, None, http)
    foo = mdx.service("https://idp.umu.se/saml2/idp/metadata.php",
                      "idpsso_descriptor", "single_sign_on_service")

    assert len(foo) == 1
    assert foo.keys()[0] == BINDING_HTTP_REDIRECT
Ejemplo n.º 16
0
def test_mdx_service():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    http = HTTPBase(verify=False, ca_bundle=None)

    mdx = MetaDataMDX(ONTS.values(), ATTRCONV, "http://pyff-test.nordu.net",
                      sec_config, None, http)
    foo = mdx.service("https://idp.umu.se/saml2/idp/metadata.php",
                      "idpsso_descriptor", "single_sign_on_service")

    assert len(foo) == 1
    assert foo.keys()[0] == BINDING_HTTP_REDIRECT
Ejemplo n.º 17
0
    def dispatch(self, request, *args, **kwargs):
        """
        Construct IDP server with config from settings dict
        """
        conf = IdPConfig()
        try:
            SAML_IDP_CONFIG = {  # pylint: disable=invalid-name
                'debug': settings.DEBUG,
                'xmlsec_binary': get_xmlsec_binary(['/opt/local/bin', '/usr/bin/xmlsec1']),
                'entityid': '%s/saml/metadata/' % settings.BASE_URL,
                'description': 'longguikeji IdP setup',

                'service': {
                    'idp': {
                        'name': 'Django localhost IdP',
                        'endpoints': {
                            'single_sign_on_service': [
                                ('%s/saml/sso/post/' % settings.BASE_URL, BINDING_HTTP_POST),
                                ('%s/saml/sso/redirect/' % settings.BASE_URL, BINDING_HTTP_REDIRECT),
                            ],
                        },
                        'name_id_format': [NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED],
                        'sign_response': True,
                        'sign_assertion': True,
                    },
                },

                'metadata': {
                    'local': [os.path.join(os.path.join(os.path.join(BASEDIR, 'djangosaml2idp'), \
                                                        'saml2_config'), f) for f in
                              os.listdir(BASEDIR + '/djangosaml2idp/saml2_config/') \
                              if f.split('.')[-1] == 'xml'],
                },
                # Signing
                'key_file': BASEDIR + '/djangosaml2idp/certificates/mykey.pem',
                'cert_file': BASEDIR + '/djangosaml2idp/certificates/mycert.pem',
                # Encryption
                'encryption_keypairs': [{
                    'key_file': BASEDIR + '/djangosaml2idp/certificates/mykey.pem',
                    'cert_file': BASEDIR + '/djangosaml2idp/certificates/mycert.pem',
                }],
                'valid_for': 365 * 24,
            }

            conf.load(copy.copy(SAML_IDP_CONFIG))
            self.IDP = Server(config=conf)  # pylint: disable=invalid-name
        except Exception as e:  # pylint: disable=invalid-name, broad-except
            return self.handle_error(request, exception=e)
        return super(IdPHandlerViewMixin,
                     self).dispatch(request, *args, **kwargs)
Ejemplo n.º 18
0
    def test_decrypt(self):
        attr_stat = saml.attribute_statement_from_string(
                            open("encrypted_attribute_statement.xml").read())

        assert len(attr_stat.attribute) == 0
        assert len(attr_stat.encrypted_attribute) == 4

        xmlsec = get_xmlsec_binary()
        sec = SecurityContext(xmlsec, key_file="private_key.pem")

        resp = AuthnResponse(sec, None, "entity_id")
        resp.decrypt_attributes(attr_stat)

        assert len(attr_stat.attribute) == 4
        assert len(attr_stat.encrypted_attribute) == 4
Ejemplo n.º 19
0
    def setup_class(self):
        xmlexec = get_xmlsec_binary()
        self.sec = sigver.SecurityContext(xmlexec, key_file=PRIV_KEY,
                                          cert_file=PUB_KEY, debug=1)

        self._assertion = factory( saml.Assertion,
            version="2.0",
            id="11111",
            issue_instant="2009-10-30T13:20:28Z",
            signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1),
            attribute_statement=do_attribute_statement({
                    ("","","surName"): ("Foo",""),
                    ("","","givenName") :("Bar",""),
                })
            )
Ejemplo n.º 20
0
def test_load_external(mock_request):
    filepath = os.path.join(TESTS_DIR, "remote_data/InCommon-metadata-export.xml")
    with open(filepath) as fd:
        data = fd.read()
    mock_request.return_value.ok = True
    mock_request.return_value.status_code = 200
    mock_request.return_value.content = data

    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["10"])
    print(mds)
    assert len(mds) == 1  # One source
    assert len(mds.keys()) > 1  # number of idps
Ejemplo n.º 21
0
def test_load_string():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["11"])
    print(mds)
    assert len(mds.keys()) == 1
    idps = mds.with_descriptor("idpsso")

    assert list(idps.keys()) == [
        'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php']
    certs = mds.certs(
        'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php',
        "idpsso", "signing")
    assert len(certs) == 1
Ejemplo n.º 22
0
def test_load_string():
    sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
    mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                        disable_ssl_certificate_validation=True)

    mds.imp(METADATACONF["11"])
    # print(mds)
    assert len(mds.keys()) == 1
    idps = mds.with_descriptor("idpsso")

    assert list(idps.keys()) == [
        'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php']
    certs = mds.certs(
        'http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php',
        "idpsso", "signing")
    assert len(certs) == 1
Ejemplo n.º 23
0
    def load(self, cnf, metadata_construction=False):
        """ The base load method, loads the configuration

        :param cnf: The configuration as a dictionary
        :param metadata_construction: Is this only to be able to construct
            metadata. If so some things can be left out.
        :return: The Configuration instance
        """
        _uc = self.unicode_convert
        for arg in COMMON_ARGS:
            if arg == "virtual_organization":
                if "virtual_organization" in cnf:
                    for key, val in cnf["virtual_organization"].items():
                        self.vorg[key] = VirtualOrg(None, key, val)
                continue

            try:
                setattr(self, arg, _uc(cnf[arg]))
            except KeyError:
                pass
            except TypeError:  # Something that can't be a string
                setattr(self, arg, cnf[arg])

        if "service" in cnf:
            for typ in ["aa", "idp", "sp", "pdp", "aq"]:
                try:
                    self.load_special(
                        cnf["service"][typ], typ,
                        metadata_construction=metadata_construction)
                    self.serves.append(typ)
                except KeyError:
                    pass

        if not metadata_construction:
            if not self.xmlsec_binary:
                self.xmlsec_binary = get_xmlsec_binary()

            # verify that xmlsec is where it's supposed to be
            if not os.path.exists(self.xmlsec_binary):
                #if not os.access(, os.F_OK):
                raise Exception(
                    "xmlsec binary not in '%s' !" % self.xmlsec_binary)

        self.load_complex(cnf, metadata_construction=metadata_construction)
        self.context = self.def_context

        return self
Ejemplo n.º 24
0
    def setup_class(self):
        xmlexec = get_xmlsec_binary()
        self.sec = sigver.SecurityContext(xmlexec,
                                          key_file=PRIV_KEY,
                                          cert_file=PUB_KEY,
                                          debug=1)

        self._assertion = factory(saml.Assertion,
                                  version="2.0",
                                  id="11111",
                                  issue_instant="2009-10-30T13:20:28Z",
                                  signature=sigver.pre_signature_part(
                                      "11111", self.sec.my_cert, 1),
                                  attribute_statement=do_attribute_statement({
                                      ("", "", "surName"): ("Foo", ""),
                                      ("", "", "givenName"): ("Bar", ""),
                                  }))
Ejemplo n.º 25
0
    def load(self, cnf, metadata_construction=False):
        """ The base load method, loads the configuration

        :param cnf: The configuration as a dictionary
        :param metadata_construction: Is this only to be able to construct
            metadata. If so some things can be left out.
        :return: The Configuration instance
        """
        for arg in COMMON_ARGS:
            if arg == "virtual_organization":
                if "virtual_organization" in cnf:
                    for key, val in cnf["virtual_organization"].items():
                        self.vorg[key] = VirtualOrg(None, key, val)
                continue

            try:
                setattr(self, arg, cnf[arg])
            except KeyError:
                pass

        if "service" in cnf:
            for typ in ["aa", "idp", "sp", "pdp"]:
                try:
                    self.load_special(
                        cnf["service"][typ],
                        typ,
                        metadata_construction=metadata_construction)
                    self.serves.append(typ)
                except KeyError:
                    pass

        if not metadata_construction:
            if not self.xmlsec_binary:
                self.xmlsec_binary = get_xmlsec_binary()

            # verify that xmlsec is where it's supposed to be
            if not os.path.exists(self.xmlsec_binary):
                #if not os.access(, os.F_OK):
                raise Exception("xmlsec binary not in '%s' !" %
                                (self.xmlsec_binary))

        self.load_complex(cnf, metadata_construction=metadata_construction)
        self.context = self.def_context

        return self
Ejemplo n.º 26
0
    def setup_class(self):
        xmlexec = get_xmlsec_binary()
        md = MetadataStore([saml, samlp], None, xmlexec)
        md.load("local", full_path("metadata_cert.xml"))

        crypto = get_xmlsec_cryptobackend()
        self.sec = sigver.SecurityContext(crypto, key_file=PRIV_KEY,
                             cert_file=PUB_KEY, debug=1, metadata=md)

        self._assertion = factory( saml.Assertion,
                                   version="2.0",
                                   id="11111",
                                   issue_instant="2009-10-30T13:20:28Z",
                                   signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1),
                                   attribute_statement=do_attribute_statement({
                                       ("","","surName"): ("Foo",""),
                                       ("","","givenName") :("Bar",""),
                                       })
        )
Ejemplo n.º 27
0
    def test_sign_assertion(self):
        ass = self._assertion
        print ass
        sign_ass = self.sec.sign_assertion_using_xmlsec("%s" % ass,
                                                        nodeid=ass.id)
        #print sign_ass
        sass = saml.assertion_from_string(sign_ass)
        #print sass
        assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant',
                                   'version', 'signature', 'id'])
        assert sass.version == "2.0"
        assert sass.id == "11111"
        assert time_util.str_to_time(sass.issue_instant)

        print xmlsec_version(get_xmlsec_binary())

        item = self.sec.check_signature(sass, class_name(sass), sign_ass)

        assert isinstance(item, saml.Assertion)
Ejemplo n.º 28
0
    def test_multiple_signatures_assertion(self):
        ass = self._assertion
        # basic test with two of the same
        to_sign = [(ass, ass.id, ''),
                   (ass, ass.id, '')
        ]
        sign_ass = self.sec.multiple_signatures("%s" % ass, to_sign)
        sass = saml.assertion_from_string(sign_ass)
        assert _eq(sass.keyswv(), ['attribute_statement', 'issue_instant',
                                   'version', 'signature', 'id'])
        assert sass.version == "2.0"
        assert sass.id == "11111"
        assert time_util.str_to_time(sass.issue_instant)

        print xmlsec_version(get_xmlsec_binary())

        item = self.sec.check_signature(sass, class_name(sass),
                                        sign_ass, must=True)

        assert isinstance(item, saml.Assertion)
Ejemplo n.º 29
0
    def test_sign_assertion(self):
        ass = self._assertion
        print ass
        sign_ass = self.sec.sign_assertion_using_xmlsec("%s" % ass,
                                                        nodeid=ass.id)
        #print sign_ass
        sass = saml.assertion_from_string(sign_ass)
        #print sass
        assert _eq(sass.keyswv(), [
            'attribute_statement', 'issue_instant', 'version', 'signature',
            'id'
        ])
        assert sass.version == "2.0"
        assert sass.id == "11111"
        assert time_util.str_to_time(sass.issue_instant)

        print xmlsec_version(get_xmlsec_binary())

        item = self.sec.check_signature(sass, class_name(sass), sign_ass)

        assert isinstance(item, saml.Assertion)
Ejemplo n.º 30
0
    def load(self, cnf, metadata_construction=False):
        """ The base load method, loads the configuration

        :param cnf: The configuration as a dictionary
        :param metadata_construction: Is this only to be able to construct
            metadata. If so some things can be left out.
        :return: The Configuration instance
        """
        for arg in COMMON_ARGS:
            try:
                self._attr[""][arg] = cnf[arg]
            except KeyError:
                pass

        if "service" in cnf:
            for typ in ["aa", "idp", "sp", "pdp"]:
                try:
                    self.load_special(
                        cnf["service"][typ],
                        typ,
                        metadata_construction=metadata_construction)

                except KeyError:
                    pass

        if not metadata_construction:
            if "xmlsec_binary" not in self._attr[""]:
                self._attr[""]["xmlsec_binary"] = get_xmlsec_binary()

            # verify that xmlsec is where it's supposed to be
            if not os.path.exists(self._attr[""]["xmlsec_binary"]):
                #if not os.access(, os.F_OK):
                raise Exception("xmlsec binary not in '%s' !" %
                                (self._attr[""]["xmlsec_binary"]))

        self.load_complex(cnf, metadata_construction=metadata_construction)
        self.context = self.def_context

        return self
Ejemplo n.º 31
0
import idp_metadata as metadata
import logging
from student.models import State, District, SubjectArea, GradeLevel, YearsInEducation, School
from baseinfo.models import Enum
from django import db
import requests
import base64

# *Guess the xmlsec_path
try:
    from saml2.sigver import get_xmlsec_binary
except ImportError:
    get_xmlsec_binary = None

if get_xmlsec_binary:
    xmlsec_path = get_xmlsec_binary()
else:
    xmlsec_path = '/usr/local/bin/xmlsec1'

SSO_DIR = settings.PROJECT_HOME + "/sso"
BASEDIR = SSO_DIR + "/idp"

log = logging.getLogger("tracking")


@csrf_exempt
def genericsso(request):
    '''Assertion consume service (acs) of pepper'''

    log.debug("===== genericsso: receiving a token =====")
Ejemplo n.º 32
0
### Everything above are default settings made by django-admin startproject
### The following is added for djangosaml2idp IdP configuration.

import saml2
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED
from saml2.sigver import get_xmlsec_binary

LOGIN_URL = '/login/'
BASE_URL = 'http://localhost:9000/idp'

SAML_IDP_CONFIG = {
    'debug':
    DEBUG,
    'xmlsec_binary':
    get_xmlsec_binary(['/opt/local/bin', '/usr/bin/xmlsec1']),
    'entityid':
    '%s/metadata' % BASE_URL,
    'description':
    'Example IdP setup',
    'service': {
        'idp': {
            'name':
            'Django localhost IdP',
            'endpoints': {
                'single_sign_on_service': [
                    ('%s/sso/post' % BASE_URL, saml2.BINDING_HTTP_POST),
                    ('%s/sso/redirect' % BASE_URL,
                     saml2.BINDING_HTTP_REDIRECT),
                ],
            },
Ejemplo n.º 33
0
                    dest='wellknown',
                    help="Use wellknown namespace prefixes")
parser.add_argument(dest="config", nargs="+")
args = parser.parse_args()

valid_for = 0
nspair = None
paths = [".", "/opt/local/bin"]

if args.valid:
    # translate into hours
    valid_for = int(args.valid) * 24
if args.xmlsec:
    xmlsec = args.xmlsec
else:
    xmlsec = get_xmlsec_binary(paths)

eds = []
for filespec in args.config:
    bas, fil = os.path.split(filespec)
    if bas != "":
        sys.path.insert(0, bas)
    if fil.endswith(".py"):
        fil = fil[:-3]
    cnf = Config().load_file(fil, metadata_construction=True)
    eds.append(entity_descriptor(cnf))

secc = SecurityContext(xmlsec, args.keyfile, cert_file=args.cert)
if args.id:
    desc = entities_descriptor(eds, valid_for, args.name, args.id, args.sign,
                               secc)
Ejemplo n.º 34
0
#!/usr/bin/env python
import json

from subprocess import Popen, PIPE
from saml2.sigver import get_xmlsec_binary

#
MAKE_METADATA = "make_metadata.py"
# or if you have problem with your paths be more specific
#MAKE_METADATA = "/usr/bin/make_metadata.py"
#MAKE_METADATA = "/Library/Frameworks/Python.framework/Versions/2.7/bin/make_metadata.py"

XMLSEC = get_xmlsec_binary(["/opt/local/bin", "/usr/local/bin"])

MDNS = '"urn:oasis:names:tc:SAML:2.0:metadata"'
NFORMAT = "xenosmilus.umdc.umu.se-8086%ssp.xml"

CNFS = [""]
COMBOS = json.loads(open("build.json").read())
CNFS.extend(COMBOS.keys())

for cnf in CNFS:

    if cnf:
        name = "conf_%s.py" % cnf
        fname = "-%s-" % cnf
    else:
        name = "conf.py"
        fname = "-"

    print 10*"=" + name + 10*"="
Ejemplo n.º 35
0
# -*- coding: utf-8 -*-
__author__ = 'roland'

from saml2 import BINDING_PAOS
from saml2 import BINDING_HTTP_ARTIFACT
from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_HTTP_REDIRECT
from saml2.sigver import get_xmlsec_binary

try:
    XMLSEC_BINARY = get_xmlsec_binary(["/opt/local/bin"])
except Exception:
    XMLSEC_BINARY = ""

# Base URL for the service
BASE = "http://localhost:8087"

# Base directory for needed files
PATH = "/Users/rolandh/code/saml2test/tests"

CONFIG = {
    "entityid": "%s/sp.xml" % BASE,
    "name": "SAML2 test tool",
    "description": "Simplest possible",
    "service": {
        "sp": {
            "allow_unsolicited": True,
            "endpoints": {
                "assertion_consumer_service": [
                    ("%s/acs/post" % BASE, BINDING_HTTP_POST),
                    ("%s/acs/redirect" % BASE, BINDING_HTTP_REDIRECT),
Ejemplo n.º 36
0
    def initAuthApp(self, application, metadataList, conf, secretFile, configfilePath=None):
        """
        Will add authentication middleware to the WSGI application.

        :param self:
        :param application: Function for main WSGI application
        :rtype : PluggableAuthenticationMiddleware
        :return:
        """

        self.CONST_SETUP = "/setup"
        self.CONST_SETUPSERVICE = "/setup/service"
        self.CONST_SETUPSTYLES = "/setup/styles"
        self.CONST_SAVESECRET = "/setup/SaveSecret"
        self.CONST_SETUPABOUT = "/setup/about"
        self.CONST_SETUPLOGUT = "/setup/logout"
        self.CONST_SESSION_USER = "******"

        self.CONST_KEY = "key"
        self.CONST_SECRET = "secret"

        if configfilePath is None:
            self.CONST_ROOT = os.path.dirname(os.path.abspath(__file__))
        else:
            self.CONST_ROOT = configfilePath

        self.CONST_AUTH_FILE = IdpSetupSp._instance.CONST_ROOT + "/auth.json"
        self.CONST_STATIC_FILE = IdpSetupSp._instance.CONST_ROOT + "/files/static/"
        self.CONST_STATIC_MAKO = IdpSetupSp._instance.CONST_ROOT + "/files/mako/"
        self.CONST_LOOKUP = TemplateLookup(directories=[self.CONST_STATIC_MAKO + 'templates', self.CONST_STATIC_MAKO + 'htdocs'],
                                           module_directory=self.CONST_STATIC_MAKO + 'modules',
                                           input_encoding='utf-8', output_encoding='utf-8')

        self.CONST_ONTS = {
            saml.NAMESPACE: saml,
            mdui.NAMESPACE: mdui,
            mdattr.NAMESPACE: mdattr,
            dri.NAMESPACE: dri,
            ui.NAMESPACE: ui,
            idpdisc.NAMESPACE: idpdisc,
            md.NAMESPACE: md,
            xmldsig.NAMESPACE: xmldsig,
            xmlenc.NAMESPACE: xmlenc
        }

        self.CONST_ATTRCONV = attribute_converter.ac_factory("attributemaps")


        try:
            xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
        except:
            try:
                xmlsec_path = get_xmlsec_binary(["/usr/local/bin"])
            except:
                xmlsec_path = '/usr/bin/xmlsec1'

        for metadata in metadataList:
            mds = MetadataStore(self.CONST_ONTS.values(), self.CONST_ATTRCONV, xmlsec_path,
                                disable_ssl_certificate_validation=True)
            mds.imp(metadata)
            for entityId in mds.keys():
                self.spKeyList.append(entityId)

        for key in conf:
            self.socialServiceKeyList.append(conf[key]["name"])

        self.secretFile = secretFile

        currentPath = os.path.dirname(os.path.abspath(__file__))
        lib_path = os.path.abspath(self.CONST_ROOT)
        sys.path.append(lib_path)
        DeclarativeAuth.getInstance(self.CONST_AUTH_FILE)
        app_with_auth = make_middleware_with_config(application, {"here": "."},
                                                    self.CONST_ROOT+'/who.ini',
                                                    log_file=self.CONST_ROOT+"/repoze_who.log")
        return app_with_auth
Ejemplo n.º 37
0
from saml2 import BINDING_HTTP_POST
from saml2.extension.idpdisc import BINDING_DISCO
from saml2.saml import NAME_FORMAT_URI

try:
    from saml2.sigver import get_xmlsec_binary
    xmlsec_path = get_xmlsec_binary(["/opt/local/bin", "/usr/local/bin", "/usr/bin/"])
except ImportError:
    xmlsec_path = '/usr/bin/xmlsec1'

# Make sure the same port number appear in service_conf.py
HOST = "localhost"
PORT = 8088
BASE = "https://%s:%s" % (HOST, PORT)

CONFIG = {
    "entityid": "%s/sp.xml" % BASE,
    "service": {
        "sp": {
            "endpoints": {
                "assertion_consumer_service": [
                    ("%s/acs/post" % BASE, BINDING_HTTP_POST)
                ],
                "single_logout_service": [
                    ("%s/slo/redirect" % BASE, BINDING_HTTP_POST),
                    ("%s/slo/post" % BASE, BINDING_HTTP_POST)
                ]

            },
            "authn_requests_signed": True,
            "logout_requests_signed": True,
Ejemplo n.º 38
0
# SAML2 IdP settings

import saml2
from saml2.saml import NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED
from saml2.sigver import get_xmlsec_binary

SESSION_COOKIE_NAME = 'sessionid_idp'

LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

SAML_IDP_BASE_URL = 'http://localhost:8000/idp'

SAML_IDP_CONFIG = {
    'debug' : DEBUG,
    'xmlsec_binary': get_xmlsec_binary(['/usr/bin/xmlsec1']),
    'entityid': '{}/metadata'.format(SAML_IDP_BASE_URL),
    'description': 'Django SAML2 IdP',

    'service': {
        'idp': {
            'name': 'Django SAML2 IdP',
            'endpoints': {
                'single_sign_on_service': [
                    ('{}/sso/post'.format(SAML_IDP_BASE_URL), saml2.BINDING_HTTP_POST),
                    ('{}/sso/redirect'.format(SAML_IDP_BASE_URL), saml2.BINDING_HTTP_REDIRECT),
                ],
            },
            'name_id_format': [NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED],
            'sign_response': True,
            'sign_assertion': True,
Ejemplo n.º 39
0
parser.add_argument('-w', dest='wellknown',
                    help="Use wellknown namespace prefixes")
parser.add_argument(dest="config", nargs="+")
args = parser.parse_args()

valid_for = 0
nspair = None
paths = [".", "/opt/local/bin"]

if args.valid:
    # translate into hours
    valid_for = int(args.valid) * 24
if args.xmlsec:
    xmlsec = args.xmlsec
else:
    xmlsec = get_xmlsec_binary(paths)

eds = []
for filespec in args.config:
    bas, fil = os.path.split(filespec)
    if bas != "":
        sys.path.insert(0, bas)
    if fil.endswith(".py"):
        fil = fil[:-3]
    cnf = Config().load_file(fil, metadata_construction=True)
    eds.append(entity_descriptor(cnf))

secc = SecurityContext(xmlsec, args.keyfile, cert_file=args.cert)
if args.id:
    desc = entities_descriptor(eds, valid_for, args.name, args.id,
                               args.sign, secc)
Ejemplo n.º 40
0
def get_saml_client(org):
    """
    Return SAML configuration.

    The configuration is a hash for use by saml2.config.Config
    """

    saml_type = org.get_setting("auth_saml_type")
    entity_id = org.get_setting("auth_saml_entity_id")
    sso_url = org.get_setting("auth_saml_sso_url")
    x509_cert = org.get_setting("auth_saml_x509_cert")
    metadata_url = org.get_setting("auth_saml_metadata_url")
    sp_settings = org.get_setting("auth_saml_sp_settings")

    if settings.SAML_SCHEME_OVERRIDE:
        acs_url = url_for(
            "saml_auth.idp_initiated",
            org_slug=org.slug,
            _external=True,
            _scheme=settings.SAML_SCHEME_OVERRIDE,
        )
    else:
        acs_url = url_for("saml_auth.idp_initiated", org_slug=org.slug, _external=True)

    saml_settings = {
        "metadata": {"remote": [{"url": metadata_url}]},
        "service": {
            "sp": {
                "endpoints": {
                    "assertion_consumer_service": [
                        (acs_url, BINDING_HTTP_REDIRECT),
                        (acs_url, BINDING_HTTP_POST),
                    ]
                },
                # Don't verify that the incoming requests originate from us via
                # the built-in cache for authn request ids in pysaml2
                "allow_unsolicited": True,
                # Don't sign authn requests, since signed requests only make
                # sense in a situation where you control both the SP and IdP
                "authn_requests_signed": False,
                "logout_requests_signed": True,
                "want_assertions_signed": True,
                "want_response_signed": False,
            }
        },
    }

    if settings.SAML_ENCRYPTION_ENABLED:
        encryption_dict = {
            "xmlsec_binary": get_xmlsec_binary(),
            "encryption_keypairs": [
                {
                    "key_file": settings.SAML_ENCRYPTION_PEM_PATH,
                    "cert_file": settings.SAML_ENCRYPTION_CERT_PATH,
                }
            ],
        }
        saml_settings.update(encryption_dict)

    if saml_type is not None and saml_type == "static":
        metadata_inline = mustache_render(
            inline_metadata_template,
            entity_id=entity_id,
            x509_cert=x509_cert,
            sso_url=sso_url,
        )

        saml_settings["metadata"] = {"inline": [metadata_inline]}

    if acs_url is not None and acs_url != "":
        saml_settings["entityid"] = acs_url

    if sp_settings:
        import json
        saml_settings["service"]["sp"].update(json.loads(sp_settings))

    sp_config = Saml2Config()
    sp_config.load(saml_settings)
    sp_config.allow_unknown_attributes = True
    saml_client = Saml2Client(config=sp_config)

    return saml_client
Ejemplo n.º 41
0
Archivo: app.py Proyecto: wlin20/arkid
from common.django.drf.serializer import DynamicFieldsModelSerializer
from oneid_meta.models import (
    APP,
    OAuthAPP,
    OIDCAPP,
    SAMLAPP,
    LDAPAPP,
    HTTPAPP,
    Dept,
    User,
)
from siteapi.v1.views.utils import gen_uid
from siteapi.v1.serializers.perm import PermWithOwnerSerializer

if get_xmlsec_binary:
    xmlsec_path = get_xmlsec_binary(["/opt/local/bin", "/usr/local/bin"])  # pylint: disable=invalid-name
else:
    xmlsec_path = '/usr/local/bin/xmlsec1'  # pylint: disable=invalid-name
BASEDIR = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.dirname(
        os.path.abspath(__file__)))))


class OAuthAPPSerializer(DynamicFieldsModelSerializer):
    '''
    Serializer for OAuthAPP
    '''
    class Meta:  # pylint: disable=missing-docstring
        model = OAuthAPP

        fields = (
Ejemplo n.º 42
0
def config_settings_loader(request: Optional[HttpRequest] = None) -> SPConfig:
    conf = SPConfig()
    if request is None or not request.path.lstrip('/').startswith(
            settings.SPID_URLS_PREFIX):
        # Not a SPID request: load SAML_CONFIG unchanged
        conf.load(copy.deepcopy(settings.SAML_CONFIG))
        return conf

    # Build a SAML_CONFIG for SPID
    metadata_url = request.build_absolute_uri(
        reverse('djangosaml2_spid:spid_metadata'))

    saml_config = {
        'entityid':
        metadata_url,
        'attribute_map_dir':
        os.path.join(djangosaml2_spid_config.path, 'attribute_maps/'),
        'service': {
            'sp': {
                'name':
                metadata_url,
                'name_qualifier':
                request.build_absolute_uri('/'),
                'name_id_format': [settings.SPID_NAMEID_FORMAT],
                'endpoints': {
                    'assertion_consumer_service': [
                        (request.build_absolute_uri(
                            reverse('djangosaml2_spid:saml2_acs')),
                         saml2.BINDING_HTTP_POST),
                    ],
                    'single_logout_service': [
                        (request.build_absolute_uri(
                            reverse('djangosaml2_spid:saml2_ls_post')),
                         saml2.BINDING_HTTP_POST),
                    ],
                },

                # Mandates that the IdP MUST authenticate the presenter directly
                # rather than rely on a previous security context.
                'force_authn':
                False,  # SPID
                'name_id_format_allow_create':
                False,

                # attributes that this project need to identify a user
                'required_attributes':
                ['spidCode', 'name', 'familyName', 'fiscalNumber', 'email'],
                'requested_attribute_name_format':
                saml2.saml.NAME_FORMAT_BASIC,
                'name_format':
                saml2.saml.NAME_FORMAT_BASIC,

                # attributes that may be useful to have but not required
                'optional_attributes': [
                    'gender', 'companyName', 'registeredOffice', 'ivaCode',
                    'idCard', 'digitalAddress', 'placeOfBirth',
                    'countyOfBirth', 'dateOfBirth', 'address', 'mobilePhone',
                    'expirationDate'
                ],
                'signing_algorithm':
                settings.SPID_SIG_ALG,
                'digest_algorithm':
                settings.SPID_DIG_ALG,
                'authn_requests_signed':
                True,
                'logout_requests_signed':
                True,

                # Indicates that Authentication Responses to this SP must
                # be signed. If set to True, the SP will not consume
                # any SAML Responses that are not signed.
                'want_assertions_signed':
                True,

                # When set to true, the SP will consume unsolicited SAML
                # Responses, i.e. SAML Responses for which it has not sent
                # a respective SAML Authentication Request.
                'allow_unsolicited':
                False,

                # Permits to have attributes not configured in attribute-mappings
                # otherwise...without OID will be rejected
                'allow_unknown_attributes':
                True,
            },
        },
        'metadata': {
            'local': [settings.SPID_IDENTITY_PROVIDERS_METADATA_DIR],
            'remote': []
        },

        # Signing
        'key_file':
        settings.SPID_PRIVATE_KEY,
        'cert_file':
        settings.SPID_PUBLIC_CERT,

        # Encryption
        'encryption_keypairs': [{
            'key_file': settings.SPID_PRIVATE_KEY,
            'cert_file': settings.SPID_PUBLIC_CERT,
        }],
        'organization':
        copy.deepcopy(settings.SAML_CONFIG['organization'])
    }

    if settings.SAML_CONFIG.get('debug'):
        saml_config['debug'] = True

    if 'xmlsec_binary' in settings.SAML_CONFIG:
        saml_config['xmlsec_binary'] = copy.deepcopy(
            settings.SAML_CONFIG['xmlsec_binary'])
    else:
        saml_config['xmlsec_binary'] = get_xmlsec_binary(
            ['/opt/local/bin', '/usr/bin/xmlsec1'])

    if settings.SPID_SAML_CHECK_REMOTE_METADATA_ACTIVE:
        saml_config['metadata']['remote'].append(
            {'url': settings.SPID_SAML_CHECK_METADATA_URL})

    if settings.SPID_TESTENV2_REMOTE_METADATA_ACTIVE:
        saml_config['metadata']['remote'].append(
            {'url': settings.SPID_TESTENV2_METADATA_URL})

    logger.debug(f'SAML_CONFIG: {saml_config}')
    conf.load(saml_config)
    return conf
Ejemplo n.º 43
0
        for alg in algs:
            if alg in DIGEST_METHODS:
                digest.append(alg)
            elif alg in SIGNING_METHODS:
                signing.append(alg)

        return {"digest": digest, "signing": signing}

    raise SystemError(p_err)


def algorithm_support_in_metadata(xmlsec):
    if xmlsec is None:
        return []

    support = get_algorithm_support(xmlsec)
    element_list = []
    for alg in support["digest"]:
        element_list.append(DigestMethod(algorithm=DIGEST_METHODS[alg]))
    for alg in support["signing"]:
        element_list.append(SigningMethod(algorithm=SIGNING_METHODS[alg]))
    return element_list


if __name__ == '__main__':
    xmlsec = get_xmlsec_binary()
    res = get_algorithm_support(xmlsec)
    print(res)
    for a in algorithm_support_in_metadata(xmlsec):
        print(a)
Ejemplo n.º 44
0
def create_conf(sp_host='sp.example.com',
                idp_hosts=['idp.example.com'],
                metadata_file='remote_metadata.xml',
                authn_requests_signed=None):

    try:
        from saml2.sigver import get_xmlsec_binary
    except ImportError:
        get_xmlsec_binary = None

    if get_xmlsec_binary:
        xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
    else:
        xmlsec_path = '/usr/bin/xmlsec1'

    BASEDIR = os.path.dirname(os.path.abspath(__file__))
    config = {
        'xmlsec_binary':
        xmlsec_path,
        'entityid':
        'http://%s/saml2/metadata/' % sp_host,
        'attribute_map_dir':
        os.path.join(BASEDIR, 'attribute-maps'),
        'service': {
            'sp': {
                'name': 'Test SP',
                'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
                'endpoints': {
                    'assertion_consumer_service': [
                        ('http://%s/saml2/acs/' % sp_host,
                         saml2.BINDING_HTTP_POST),
                    ],
                    'single_logout_service': [
                        ('http://%s/saml2/ls/' % sp_host,
                         saml2.BINDING_HTTP_REDIRECT),
                    ],
                },
                'required_attributes': ['uid'],
                'optional_attributes': ['eduPersonAffiliation'],
                'idp': {},  # this is filled later
                'want_response_signed': False,
            },
        },
        'metadata': {
            'local': [os.path.join(BASEDIR, metadata_file)],
        },
        'debug':
        1,

        # certificates
        'key_file':
        os.path.join(BASEDIR, 'mycert.key'),
        'cert_file':
        os.path.join(BASEDIR, 'mycert.pem'),

        # These fields are only used when generating the metadata
        'contact_person': [
            {
                'given_name': 'Technical givenname',
                'sur_name': 'Technical surname',
                'company': 'Example Inc.',
                'email_address': '*****@*****.**',
                'contact_type': 'technical'
            },
            {
                'given_name': 'Administrative givenname',
                'sur_name': 'Administrative surname',
                'company': 'Example Inc.',
                'email_address': '*****@*****.**',
                'contact_type': 'administrative'
            },
        ],
        'organization': {
            'name': [('Ejemplo S.A.', 'es'), ('Example Inc.', 'en')],
            'display_name': [('Ejemplo', 'es'), ('Example', 'en')],
            'url': [('http://www.example.es', 'es'),
                    ('http://www.example.com', 'en')],
        },
        'valid_for':
        24,
    }

    if authn_requests_signed is not None:
        config['service']['sp'][
            'authn_requests_signed'] = authn_requests_signed

    for idp in idp_hosts:
        entity_id = 'https://%s/simplesaml/saml2/idp/metadata.php' % idp
        config['service']['sp']['idp'][entity_id] = {
            'single_sign_on_service': {
                saml2.BINDING_HTTP_REDIRECT:
                'https://%s/simplesaml/saml2/idp/SSOService.php' % idp,
            },
            'single_logout_service': {
                saml2.BINDING_HTTP_REDIRECT:
                'https://%s/simplesaml/saml2/idp/SingleLogoutService.php' %
                idp,
            },
        }

    return config
Ejemplo n.º 45
0
# -*- coding: utf-8 -*-

from saml2 import BINDING_PAOS
from saml2 import BINDING_HTTP_ARTIFACT
from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_HTTP_REDIRECT
from saml2.sigver import get_xmlsec_binary

try:
    XMLSEC_BINARY = get_xmlsec_binary(["/opt/local/bin"])
except Exception:
    XMLSEC_BINARY = "/usr/bin/xmlsec1"

PORT = 8087

# Base URL for the service
BASE = "http://localhost:{port}".format(port=PORT)

# Base directory for needed files

CONFIG = {
    "entityid": "%s/sp.xml" % BASE,
    "name": "SAML2 test tool",
    "description": "Simplest possible",
    "service": {
        "sp": {
            "allow_unsolicited": True,
            "authn_requests_signed": "true",
            "endpoints": {
                "assertion_consumer_service": [
                    ("%s/acs/post" % BASE, BINDING_HTTP_POST),
Ejemplo n.º 46
0
# -*- coding: utf-8 -*-

from saml2 import BINDING_SOAP, BINDING_URI
from saml2 import BINDING_HTTP_REDIRECT
from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_HTTP_ARTIFACT
from saml2.saml import NAMEID_FORMAT_PERSISTENT
from saml2.saml import NAME_FORMAT_URI

try:
    from saml2.sigver import get_xmlsec_binary
except ImportError:
    get_xmlsec_binary = None

if get_xmlsec_binary:
    xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
else:
    xmlsec_path = '/usr/bin/xmlsec1'

BASE = "http://localhost:8088"

CONFIG = {
    "entityid" : "urn:mace:example.com:saml:roland:idp",
    "name" : "Rolands IdP",
    "service": {
        "aa": {
            "endpoints" : {
                "attribute_service": [
                    ("%s/aap" % BASE, BINDING_HTTP_POST),
                    ("%s/aas" % BASE, BINDING_SOAP)
                ]
Ejemplo n.º 47
0
                retcode = p.poll()  #returns None while subprocess is running
                if (retcode is not None):
                    break
            p_out = p.stdout.read()
            p_err = p.stderr.read()
            return (True, p_out, p_err)
        except Exception as ex:
            return (False, None, None)


MAKE_METADATA = "make_metadata.py"
# or if you have problem with your paths be more specific
#MAKE_METADATA = "/usr/bin/make_metadata.py"
#MAKE_METADATA = "/Library/Frameworks/Python.framework/Versions/2.7/bin/make_metadata.py"

XMLSEC = get_xmlsec_binary(["/opt/local/bin", "/usr/local/bin"])

MDNS = '"urn:oasis:names:tc:SAML:2.0:metadata"'
NFORMAT = "{HOST}%ssp.xml".format(HOST=server_conf.HOST)

CNFS = [""]
COMBOS = json.loads(open("build.json").read())
CNFS.extend(COMBOS.keys())

fname_list = []

for cnf in CNFS:

    if cnf:
        name = "conf_%s.py" % cnf
        fname = "-%s-" % cnf
Ejemplo n.º 48
0
        signing = []
        for alg in algs:
            if alg in DIGEST_METHODS:
                digest.append(alg)
            elif alg in SIGNING_METHODS:
                signing.append(alg)

        return {"digest": digest, "signing": signing}

    raise SystemError(p_err)


def algorithm_support_in_metadata(xmlsec):
    if xmlsec is None:
        return []

    support = get_algorithm_support(xmlsec)
    element_list = []
    for alg in support["digest"]:
        element_list.append(DigestMethod(algorithm=DIGEST_METHODS[alg]))
    for alg in support["signing"]:
        element_list.append(SigningMethod(algorithm=SIGNING_METHODS[alg]))
    return element_list

if __name__ == '__main__':
    xmlsec = get_xmlsec_binary()
    res = get_algorithm_support(xmlsec)
    print(res)
    for a in algorithm_support_in_metadata(xmlsec):
        print(a)
Ejemplo n.º 49
0
import os

from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT, BINDING_SOAP
from saml2.saml import NAME_FORMAT_URI, NAMEID_FORMAT_PERSISTENT, NAMEID_FORMAT_TRANSIENT

try:
    from saml2.sigver import get_xmlsec_binary
except ImportError:
    get_xmlsec_binary = None

if get_xmlsec_binary:
    xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
else:
    xmlsec_path = '/usr/bin/xmlsec1'

_hostname = 'unittest-idp.example.edu'
BASE = "https://{!s}".format(_hostname)

here = os.path.dirname(__file__)
key_path = os.path.join(here, 'idp-public-snakeoil.key')
cert_path = os.path.join(here, 'idp-public-snakeoil.pem')

attrmaps_path = os.path.join(here, '../../../attributemaps')
sp_metadata_path = os.path.join(here, 'sp_metadata.xml')


CONFIG = {
    "entityid": "%s/idp.xml" % BASE,
    "description": "eduID UNITTEST identity provider",
    "service": {
        "idp": {
Ejemplo n.º 50
0
import os

from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
from saml2.saml import NAME_FORMAT_URI

try:
    from saml2.sigver import get_xmlsec_binary
except ImportError:
    get_xmlsec_binary = None

if get_xmlsec_binary:
    xmlsec_path = get_xmlsec_binary(['/opt/local/bin', '/usr/local/bin'])
else:
    xmlsec_path = '/usr/local/bin/xmlsec1'

# Make sure the same port number appear in service_conf.py
BASEDIR = os.path.abspath(os.path.dirname(__file__))
BASE = 'https://sp-url.rackspace.com'

SSL_CERT_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 'pki')
CERT = os.path.join(SSL_CERT_LOCATION, 'sp.crt')
IDP_METADATA_LOCATION = os.getenv(
    'IDP_METADATA_LOCATION', os.path.join(SSL_CERT_LOCATION,
                                          'idp_metadata.xml'))
PRIVATE_KEY = os.path.join(SSL_CERT_LOCATION, 'sp.key')

CONFIG = {
    'entityid': BASE,
    'service': {
        'sp': {
ONTS = {
    saml.NAMESPACE: saml,
    mdui.NAMESPACE: mdui,
    mdattr.NAMESPACE: mdattr,
    dri.NAMESPACE: dri,
    ui.NAMESPACE: ui,
    idpdisc.NAMESPACE: idpdisc,
    md.NAMESPACE: md,
    xmldsig.NAMESPACE: xmldsig,
    xmlenc.NAMESPACE: xmlenc
}

ATTRCONV = ac_factory(full_path("attributemaps"))
sec_config = config.Config()
sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])

__author__ = 'rolandh'

MDS = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                    disable_ssl_certificate_validation=True)
MDS.imp([{"class": "saml2.mdstore.MetaDataMD", "metadata": [(full_path("swamid.md"), )]}])


def _eq(l1, l2):
    return set(l1) == set(l2)


def test_filter_ava():
    policy = Policy({
        "default": {
Ejemplo n.º 52
0
ONTS = {
    saml.NAMESPACE: saml,
    mdui.NAMESPACE: mdui,
    mdattr.NAMESPACE: mdattr,
    dri.NAMESPACE: dri,
    ui.NAMESPACE: ui,
    idpdisc.NAMESPACE: idpdisc,
    md.NAMESPACE: md,
    xmldsig.NAMESPACE: xmldsig,
    xmlenc.NAMESPACE: xmlenc
}

ATTRCONV = ac_factory(full_path("attributemaps"))
sec_config = config.Config()
sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])

__author__ = 'rolandh'

MDS = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
                    disable_ssl_certificate_validation=True)
MDS.imp([{"class": "saml2.mdstore.MetaDataMD", "metadata": [(full_path("swamid.md"), )]}])


def _eq(l1, l2):
    return set(l1) == set(l2)


def test_filter_ava():
    policy = Policy({
        "default": {
Ejemplo n.º 53
0
from saml2 import BINDING_HTTP_POST
from saml2.extension.idpdisc import BINDING_DISCO
from saml2.saml import NAME_FORMAT_URI

try:
    from saml2.sigver import get_xmlsec_binary
    xmlsec_path = get_xmlsec_binary(
        ["/opt/local/bin", "/usr/local/bin", "/usr/bin/"])
except ImportError:
    xmlsec_path = '/usr/bin/xmlsec1'

# Make sure the same port number appear in service_conf.py
HOST = "localhost"
PORT = 8088
BASE = "https://%s:%s" % (HOST, PORT)

CONFIG = {
    "entityid": "%s/sp.xml" % BASE,
    "service": {
        "sp": {
            "endpoints": {
                "assertion_consumer_service":
                [("%s/acs/post" % BASE, BINDING_HTTP_POST)],
                "single_logout_service":
                [("%s/slo/redirect" % BASE, BINDING_HTTP_POST),
                 ("%s/slo/post" % BASE, BINDING_HTTP_POST)]
            },
            "authn_requests_signed": True,
            "logout_requests_signed": True,
            "want_assertions_signed": True
        },
Ejemplo n.º 54
0
def config_settings_loader(request: Optional[HttpRequest] = None) -> SPConfig:
    conf = SPConfig()
    if request is None:
        # Not a SPID request: load SAML_CONFIG unchanged
        conf.load(copy.deepcopy(settings.SAML_CONFIG))
        return conf

    # Build a SAML_CONFIG for SPID
    base_url = settings.SPID_BASE_URL or request.build_absolute_uri("/")
    metadata_url = urljoin(base_url, settings.SPID_METADATA_URL_PATH)

    if settings.SPID_METADATA_URL_PATH in request.get_full_path():
        _REQUIRED_ATTRIBUTES = settings.SPID_REQUIRED_ATTRIBUTES
        _OPTIONAL_ATTRIBUTES = settings.SPID_OPTIONAL_ATTRIBUTES
    else:
        _REQUIRED_ATTRIBUTES = settings.CIE_REQUIRED_ATTRIBUTES
        _OPTIONAL_ATTRIBUTES = []

    saml_config = {
        "entityid":
        getattr(settings, 'SAML2_ENTITY_ID', metadata_url),
        "attribute_map_dir":
        settings.SPID_ATTR_MAP_DIR,
        "service": {
            "sp": {
                "name":
                metadata_url,
                "name_qualifier":
                base_url,
                "name_id_format": [settings.SPID_NAMEID_FORMAT],
                "endpoints": {
                    "assertion_consumer_service": [
                        (
                            urljoin(base_url,
                                    reverse("djangosaml2_spid:saml2_acs")),
                            saml2.BINDING_HTTP_POST,
                        ),
                    ],
                    "single_logout_service": [
                        (
                            urljoin(base_url,
                                    reverse("djangosaml2_spid:saml2_ls_post")),
                            saml2.BINDING_HTTP_POST,
                        ),
                    ],
                },
                # Mandates that the IdP MUST authenticate the presenter directly
                # rather than rely on a previous security context.
                "force_authn":
                False,  # SPID
                "name_id_format_allow_create":
                False,
                # attributes that this project need to identify a user
                "required_attributes":
                _REQUIRED_ATTRIBUTES,
                "optional_attributes":
                _OPTIONAL_ATTRIBUTES,
                "requested_attribute_name_format":
                saml2.saml.NAME_FORMAT_BASIC,
                "name_format":
                saml2.saml.NAME_FORMAT_BASIC,
                "signing_algorithm":
                settings.SPID_SIG_ALG,
                "digest_algorithm":
                settings.SPID_DIG_ALG,
                "authn_requests_signed":
                True,
                "logout_requests_signed":
                True,
                # Indicates that Authentication Responses to this SP must
                # be signed. If set to True, the SP will not consume
                # any SAML Responses that are not signed.
                "want_assertions_signed":
                True,
                # When set to true, the SP will consume unsolicited SAML
                # Responses, i.e. SAML Responses for which it has not sent
                # a respective SAML Authentication Request. Set to True to
                # let ACS endpoint work.
                "allow_unsolicited":
                settings.SAML_CONFIG.get("allow_unsolicited", False),
                # Permits to have attributes not configured in attribute-mappings
                # otherwise...without OID will be rejected
                "allow_unknown_attributes":
                True,
            },
        },
        "disable_ssl_certificate_validation":
        settings.SAML_CONFIG.get("disable_ssl_certificate_validation"),
        "metadata": {
            "local": [settings.SPID_IDENTITY_PROVIDERS_METADATA_DIR],
            "remote": [],
        },
        # Signing
        "key_file":
        settings.SPID_PRIVATE_KEY,
        "cert_file":
        settings.SPID_PUBLIC_CERT,
        # Encryption
        "encryption_keypairs": [{
            "key_file": settings.SPID_PRIVATE_KEY,
            "cert_file": settings.SPID_PUBLIC_CERT,
        }],
        "organization":
        copy.deepcopy(settings.SAML_CONFIG["organization"]),
    }

    if settings.SAML_CONFIG.get("debug"):
        saml_config["debug"] = True

    if "xmlsec_binary" in settings.SAML_CONFIG:
        saml_config["xmlsec_binary"] = copy.deepcopy(
            settings.SAML_CONFIG["xmlsec_binary"])
    else:
        saml_config["xmlsec_binary"] = get_xmlsec_binary(
            ["/opt/local/bin", "/usr/bin/xmlsec1"])

    if settings.SPID_SAML_CHECK_IDP_ACTIVE:
        saml_config["metadata"]["remote"].append(
            {"url": settings.SPID_SAML_CHECK_METADATA_URL})

    if settings.SPID_DEMO_IDP_ACTIVE:
        saml_config["metadata"]["remote"].append(
            {"url": settings.SPID_DEMO_METADATA_URL})

    if settings.SPID_VALIDATOR_IDP_ACTIVE:
        saml_config["metadata"]["remote"].append(
            {"url": settings.SPID_VALIDATOR_METADATA_URL})

    logger.debug(f"SAML_CONFIG: {saml_config}")
    conf.load(saml_config)
    return conf
Ejemplo n.º 55
0
    def get_saml2_config(self):
        """
        Configures a Saml2Client with the given settings

        SAML2 based SSO(Single-Sign-On) identity provider with dynamic metadata configuration

        https://pysaml2.readthedocs.io/en/latest/howto/config.html
        """

        saml_settings = {
            # "entityid": None,
            # "description": "Example SP",
            'service': {
                'sp': {
                    'endpoints': {
                        'assertion_consumer_service':
                        [(self.acs_url, BINDING_HTTP_REDIRECT),
                         (self.acs_url, BINDING_HTTP_POST)],
                        # Other Valid endpoints not configured yet
                        #'artifact_resolution_service': []
                        #"single_logout_service": []
                    },
                    # this is overriden if a key is available
                    'authn_requests_signed': False,
                    'allow_unsolicited': True,  # this is needed for POST

                    # Indicates that either the Authentication Response or the assertions contained
                    # within the response to this SP must be signed. Check DOCS
                    'want_assertions_signed': False,
                    'want_response_signed': False,
                    "want_assertions_or_response_signed": True,
                },
            },
        }

        if 'METADATA_LOCAL_FILE_PATH' in self.settings:
            update(saml_settings, {
                'metadata': {
                    'local': [self.settings['METADATA_LOCAL_FILE_PATH']]
                }
            })
        elif 'METADATA_AUTO_CONF_URL' in self.settings:
            update(
                saml_settings, {
                    'metadata': {
                        'remote': [
                            {
                                "url": self.settings['METADATA_AUTO_CONF_URL'],
                            },
                        ]
                    }
                })
        else:
            raise Saml2Error("IdP metadata missing")

        if 'ENTITY_ID' in self.settings:
            saml_settings['entityid'] = self.settings['ENTITY_ID']
        else:
            # EntityId: It is recommended that the entityid should point to a real webpage where the metadata
            # for the entity can be found. TODO: make this true
            uri = urlparse(self.acs_url)
            saml_settings['entityid'] = f'{uri.scheme}://{uri.netloc}'

        if 'NAME_ID_FORMAT' in self.settings:
            saml_settings['service']['sp']['name_id_format'] = self.settings[
                'NAME_ID_FORMAT']

        if 'ACCEPTED_TIME_DIFF' in self.settings:
            saml_settings['accepted_time_diff'] = self.settings[
                'ACCEPTED_TIME_DIFF']

        if 'KEY_FILE' in self.settings and 'CERT_FILE' in self.settings:
            try:
                from saml2.sigver import get_xmlsec_binary
            except ImportError:
                get_xmlsec_binary = None

            if get_xmlsec_binary:
                xmlsec_path = get_xmlsec_binary(
                    ["/opt/local/bin", "/usr/local/bin"])
            else:
                xmlsec_path = '/usr/local/bin/xmlsec1'

            update(
                saml_settings, {
                    'service': {
                        'sp': {
                            "authn_requests_signed": True
                        }
                    },
                    "key_file": self.settings['KEY_FILE'],
                    "cert_file": self.settings['CERT_FILE'],
                    "xmlsec_binary": xmlsec_path,
                })

        # TODO: add encryption_keypairs

        return saml_settings
Ejemplo n.º 56
0
def create_conf(sp_host='sp.example.com', idp_hosts=['idp.example.com'],
                metadata_file='remote_metadata.xml'):

    try:
        from saml2.sigver import get_xmlsec_binary
    except ImportError:
        get_xmlsec_binary = None

    if get_xmlsec_binary:
        xmlsec_path = get_xmlsec_binary(["/opt/local/bin"])
    else:
        xmlsec_path = '/usr/bin/xmlsec1'

    BASEDIR = os.path.dirname(os.path.abspath(__file__))
    config = {
        'xmlsec_binary': xmlsec_path,
        'entityid': 'http://%s/saml2/metadata/' % sp_host,
        'attribute_map_dir': os.path.join(BASEDIR, 'attribute-maps'),

        'service': {
            'sp': {
                'name': 'Test SP',
                'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
                'endpoints': {
                    'assertion_consumer_service': [
                        ('http://%s/saml2/acs/' % sp_host,
                         saml2.BINDING_HTTP_POST),
                        ],
                    'single_logout_service': [
                        ('http://%s/saml2/ls/' % sp_host,
                         saml2.BINDING_HTTP_REDIRECT),
                        ],
                    },
                'required_attributes': ['uid'],
                'optional_attributes': ['eduPersonAffiliation'],
                'idp': {}  # this is filled later
                },
            },

        'metadata': {
            'local': [os.path.join(BASEDIR, metadata_file)],
            },

        'debug': 1,

        # certificates
        'key_file': os.path.join(BASEDIR, 'mycert.key'),
        'cert_file': os.path.join(BASEDIR, 'mycert.pem'),

        # These fields are only used when generating the metadata
        'contact_person': [
            {'given_name': 'Technical givenname',
             'sur_name': 'Technical surname',
             'company': 'Example Inc.',
             'email_address': '*****@*****.**',
             'contact_type': 'technical'},
            {'given_name': 'Administrative givenname',
             'sur_name': 'Administrative surname',
             'company': 'Example Inc.',
             'email_address': '*****@*****.**',
             'contact_type': 'administrative'},
            ],
        'organization': {
            'name': [('Ejemplo S.A.', 'es'), ('Example Inc.', 'en')],
            'display_name': [('Ejemplo', 'es'), ('Example', 'en')],
            'url': [('http://www.example.es', 'es'),
                    ('http://www.example.com', 'en')],
            },
        'valid_for': 24,
        }

    for idp in idp_hosts:
        entity_id = 'https://%s/simplesaml/saml2/idp/metadata.php' % idp
        config['service']['sp']['idp'][entity_id] = {
            'single_sign_on_service': {
                saml2.BINDING_HTTP_REDIRECT: 'https://%s/simplesaml/saml2/idp/SSOService.php' % idp,
                },
            'single_logout_service': {
                saml2.BINDING_HTTP_REDIRECT: 'https://%s/simplesaml/saml2/idp/SingleLogoutService.php' % idp,
                },
            }

    return config