Example #1
0
File: idp.py Project: ging/keystone
def _sign_assertion(assertion):
    """Sign a SAML assertion.

    This method utilizes ``xmlsec1`` binary and signs SAML assertions in a
    separate process. ``xmlsec1`` cannot read input data from stdin so the
    prepared assertion needs to be serialized and stored in a temporary
    file. This file will be deleted immediately after ``xmlsec1`` returns.
    The signed assertion is redirected to a standard output and read using
    subprocess.PIPE redirection. A ``saml.Assertion`` class is created
    from the signed string again and returned.

    Parameters that are required in the CONF::
    * xmlsec_binary
    * private key file path
    * public key file path
    :return: XML <Assertion> object

    """
    xmlsec_binary = CONF.saml.xmlsec1_binary
    idp_private_key = CONF.saml.keyfile
    idp_public_key = CONF.saml.certfile

    # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file>
    certificates = '%(idp_private_key)s,%(idp_public_key)s' % {
        'idp_public_key': idp_public_key,
        'idp_private_key': idp_private_key
    }

    command_list = [xmlsec_binary, '--sign', '--privkey-pem', certificates,
                    '--id-attr:ID', 'Assertion']

    try:
        # NOTE(gyee): need to make the namespace prefixes explicit so
        # they won't get reassigned when we wrap the assertion into
        # SAML2 response
        file_path = fileutils.write_to_tempfile(assertion.to_string(
            nspair={'saml': saml2.NAMESPACE,
                    'xmldsig': xmldsig.NAMESPACE}))
        command_list.append(file_path)
        process = subprocess.Popen(command_list,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   close_fds=True)
        stdout, stderr = process.communicate()
        retcode = process.poll()
        if retcode:
            msg = _LE('Error when signing assertion, reason: %(reason)s')
            msg = msg % {'reason': stderr}
            LOG.error(msg)
            raise exception.SAMLSigningError(reason=stderr)
    finally:
        try:
            os.remove(file_path)
        except OSError:
            pass

    return saml2.create_class_from_xml_string(saml.Assertion, stdout)
Example #2
0
def _sign_assertion(assertion):
    """Sign a SAML assertion.

    This method utilizes ``xmlsec1`` binary and signs SAML assertions in a
    separate process. ``xmlsec1`` cannot read input data from stdin so the
    prepared assertion needs to be serialized and stored in a temporary
    file. This file will be deleted immediately after ``xmlsec1`` returns.
    The signed assertion is redirected to a standard output and read using
    subprocess.PIPE redirection. A ``saml.Assertion`` class is created
    from the signed string again and returned.

    Parameters that are required in the CONF::
    * xmlsec_binary
    * private key file path
    * public key file path
    :return: XML <Assertion> object

    """
    xmlsec_binary = CONF.saml.xmlsec1_binary
    idp_private_key = CONF.saml.keyfile
    idp_public_key = CONF.saml.certfile

    # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file>
    certificates = '%(idp_private_key)s,%(idp_public_key)s' % {
        'idp_public_key': idp_public_key,
        'idp_private_key': idp_private_key
    }

    command_list = [
        xmlsec_binary, '--sign', '--privkey-pem', certificates, '--id-attr:ID',
        'Assertion'
    ]

    try:
        # NOTE(gyee): need to make the namespace prefixes explicit so
        # they won't get reassigned when we wrap the assertion into
        # SAML2 response
        file_path = fileutils.write_to_tempfile(
            assertion.to_string(nspair={
                'saml': saml2.NAMESPACE,
                'xmldsig': xmldsig.NAMESPACE
            }))
        command_list.append(file_path)
        stdout = subprocess.check_output(command_list)
    except Exception as e:
        msg = _LE('Error when signing assertion, reason: %(reason)s')
        msg = msg % {'reason': e}
        LOG.error(msg)
        raise exception.SAMLSigningError(reason=e)
    finally:
        try:
            os.remove(file_path)
        except OSError:
            pass

    return saml2.create_class_from_xml_string(saml.Assertion, stdout)
Example #3
0
def _sign_assertion(assertion):
    """Sign a SAML assertion.

    This method utilizes ``xmlsec1`` binary and signs SAML assertions in a
    separate process. ``xmlsec1`` cannot read input data from stdin so the
    prepared assertion needs to be serialized and stored in a temporary
    file. This file will be deleted immediately after ``xmlsec1`` returns.
    The signed assertion is redirected to a standard output and read using
    subprocess.PIPE redirection. A ``saml.Assertion`` class is created
    from the signed string again and returned.

    Parameters that are required in the CONF::
    * xmlsec_binary
    * private key file path
    * public key file path
    :return: XML <Assertion> object

    """
    xmlsec_binary = CONF.saml.xmlsec1_binary
    idp_private_key = CONF.saml.keyfile
    idp_public_key = CONF.saml.certfile

    # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file>
    certificates = '%(idp_private_key)s,%(idp_public_key)s' % {
        'idp_public_key': idp_public_key,
        'idp_private_key': idp_private_key
    }

    command_list = [xmlsec_binary, '--sign', '--privkey-pem', certificates,
                    '--id-attr:ID', 'Assertion']

    try:
        file_path = fileutils.write_to_tempfile(assertion.to_string())
        command_list.append(file_path)
        stdout = subprocess.check_output(command_list)
    except Exception as e:
        msg = _LE('Error when signing assertion, reason: %(reason)s')
        msg = msg % {'reason': e}
        LOG.error(msg)
        raise exception.SAMLSigningError(reason=e)
    finally:
        try:
            os.remove(file_path)
        except OSError:
            pass

    return saml2.create_class_from_xml_string(saml.Assertion, stdout)