Skip to content

Problem working with OpenVPN AS #574

@y3k00000

Description

@y3k00000

Been tried developing a small service for OpenVPN Access Server. But no luck.

Using the Express.js code below:

const testOpenVpn = async () => {
    const express = require('express');

    const idpOpenVpnTest = saml.IdentityProvider({
        metadata: fs.readFileSync(path.join(__dirname, 'misc/metadata-ip-bridge-openvpn.xml')),
        privateKey: fs.readFileSync(path.join(__dirname, 'misc/key.pem')),
    });
    const spOpenVpnTest = saml.ServiceProvider({
        metadata: fs.readFileSync(path.join(__dirname, 'misc/metadata-sp-bridge-openvpn.xml')),
    });
    const app = express();
    app.get("/", async (req, res) => {
        let idp = idpOpenVpnTest;
        let sp = spOpenVpnTest;
        const samlRequest = req.query.SAMLRequest;
        const samlSigAlg = req.query.SigAlg;
        const samlSignature = req.query.Signature;
        const samlOctetQueryString = Object.keys(req.query).filter(q => q != "Signature").map(q => q + '=' + encodeURIComponent(req.query[q])).join('&');
        const receivedRequest = { query: { SAMLRequest: samlRequest, SigAlg: samlSigAlg, Signature: samlSignature }, octetString: samlOctetQueryString };
        const parsedLoginRequest = await idp.parseLoginRequest(sp, 'redirect', receivedRequest);
        const user = { email: "samlifyer" };
        const loginResponse = await idp.createLoginResponse(sp, parsedLoginRequest, 'post', user, null, true, saml.Constants.StatusCode.Success);
        let renderHtml = fs.readFileSync(path.join(__dirname, 'testbench-redirect.html'), 'utf-8');
        let samlResponse = loginResponse.context;
        /* This doesn't work. */
        // samlResponse = Buffer.from(samlResponse, 'base64').toString('utf-8');
        // let samlIssueInstant = new Date().toISOString();
        // let samlSessionIndex = uuidv4();
        // samlResponse = samlResponse.replace("</saml:Conditions></saml:Assertion>", `</saml:Conditions><saml:AuthnStatement AuthnInstant="${samlIssueInstant}" SessionIndex="${samlSessionIndex}"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>`);
        // samlResponse = Buffer.from(samlResponse, 'utf-8').toString('base64');
        /* End of : This doesn't work. */
        renderHtml = renderHtml.replace("{{samlResponse}}", samlResponse);
        renderHtml = renderHtml.replace("{{redirectUrl}}", loginResponse.entityEndpoint);
        renderHtml = renderHtml.replace("{{relayState}}", req.query.RelayState);
        res.contentType(".html").status(200).send(renderHtml);
    });

    app.listen(1234, () => {
        console.log("OpenVPN test server started on port 1234");
    });
};

The sso service on idp just renders a button that will post the form back to openvpn.

But in openvpn there says :

Image

I tried adding AuthnStatement myself which do works in another earlier project but is getting signature error from openvpn. In This doesn't work block.

Been reading the other issue and traced down the function calls I found the base64LoginResponse() in binding-post.ts puts the AuthnStatement empty statically.

Image

Don't know what to do now. It seems not only my last work with a custom project but also openvpn is having this problem. I'd think we need a structured AuthnStatement option/argument for these function calls? Or is there anymore workaround I can do?

Thanks for any help in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions