Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to delegate the authentication to external programs #974

Merged
merged 1 commit into from
Jun 13, 2022

Conversation

gm-vm
Copy link
Contributor

@gm-vm gm-vm commented Apr 2, 2022

Some users are required to login with SAML and perform multi-factor authentications. In some cases performing the authentication without a browser is close to impossible, so it is best to delegate the operation to external programs.
This also allows to move the complexity of dealing with different SAML providers out of openfortivpn.

These changes allow users to authenticate in two different ways:

  • Passing a valid SVPNCOOKIE through a new command line argument (--cookie).
    Users are in this case expected to know how to retrieve the cookie.
    This option is not strictly related to SAML, even though that is likely the main reason for using it.
  • Specifying a command that will be executed to retrieve the SVPNCOOKIE (--saml-handler).
    The command will receive the URL for the SAML authentication as argument.

@gm-vm
Copy link
Contributor Author

gm-vm commented Apr 2, 2022

Relevant issue: #867

I'm still not sure what is the best way to handle this.

I've added two options simply because I find having GUI applications launched directly by openfortivpn not straightforward.
GUI application may require many env variables to be set and making sure everything is setup correctly can be painful.

Requiring the cookie to be passed as argument makes that easy, at least in my opinion.
I've also considered the possibility of having it passed in through stdin, but I decided to copy the behavior of the --otp option.

@gm-vm
Copy link
Contributor Author

gm-vm commented Apr 2, 2022

Some additional notes.

I have written an application to automate the extraction of SVPNCOOKIE when dealing with SAML, but you can use any browser.

According to this the SAML page should be at https://HOST:PORT/remote/saml/start, or https://HOST:PORT/remote/saml/start?realm=REALM if you normally use the --realm option.

I have tested this with Cisco Duo, which requires me to login using my credentials and authorize the access through a mobile application. As soon as I authorize the access I receive the SVPNCOOKIE and I land to some Fortinet page.

If the VPN dies while the browser is open, that webpage will try to recover it by sending a new push notification to the mobile app. No credentials required in this case. This means that keeping the browser open may be desired, especially with an unstable connection.

I do not know if this is the behavior of every SAML provider, but this is what I observed.

To have a persistent VPN when using --cookie I would use something like the following (just a proof of concept, I did not actually try it as I don't need something this complex with my VPN):

#!/bin/sh

(openfortivpn-webview myhost.com:443 --keep-open > /tmp/svpncookie) &

while true; do
    cookie="$(cat /tmp/svpncookie)"
    > /tmp/svpncookie
    if [ -n "$cookie" ]; then
        sudo openfortivpn myhost.com:443 --cookie "$cookie"
    fi
    sleep 5
done

If your SAML page is simple you could even script everything with something like curl.

@gm-vm
Copy link
Contributor Author

gm-vm commented Apr 3, 2022

The only reason why I kept --saml-handler here is that I have mentioned it already in the issue linked. However, I do not really see the need for it. It is nice that it gives you the correct URL, but that's pretty much it. With SAML you don't have to provide the password, so everything can be in a script in plain sight. --reconnect can be easily simulated with a while loop in my opinion.

I'm still not sure about the cookie being passed through command line arguments. Even if it gets disposed rather frequently, it's still something you may want to keep secret and command line arguments are not. I liked the idea of having it passed through stdin. That can be made optional using the conventional -, as I did in one of my experiments.

For the record, my previous script could be improved with a named pipe. With that openfortivpn can wait for the cookie to be available before trying to bring up the VPN.

#!/bin/sh

pipe="/tmp/openfortivpn-cookie"
mkfifo "$pipe"
chmod 0622 "$pipe" # Anyone can write, only root can read.

while true; do
    echo "Waiting for a cookie..."
    read line < "$pipe"
    openfortivpn host:port --cookie "$line"
done

# remove "$pipe", possibly using a 'trap'

The above does not handle the case in which openfortivpn loses the connection, but the cookie remains valid. For that one can try this:

#!/bin/bash

pipe="/tmp/openfortivpn-cookie"
mkfifo "$pipe"
chmod 0622 "$pipe" # Anyone can write, only root can read.

# Wait for the first cookie
echo "Waiting for a cookie..."
read cookie < "$pipe"

while true; do
    openfortivpn host:port --cookie "$cookie"

    # Wait for up to 10 seconds to receive a new cookie.
    # If not cookie is provided, keep using the old cookie.
    echo "Waiting 10 seconds for a new cookie..."
    read line -t 10 <> "$pipe" # not portable, bash may be required

    if [ -n "$line" ]; then
        # In case 'read' times out, "$line" is empty
        cookie="$line"
    fi
done

@gm-vm
Copy link
Contributor Author

gm-vm commented Apr 9, 2022

I removed the --saml-handler option, it can be added later if needed.

openfortivpn has an extremely fast startup, so I don't see too many differences between a while loop in a shell script and the --reconnect option. Especially with SAML, since the session cookie must come from somewhere else.

I think that just requiring the cookie is flexible and it allows to easily use openfortivpn with other applications.

@gm-vm gm-vm marked this pull request as ready for review April 9, 2022 10:44
@joso9001 joso9001 mentioned this pull request May 6, 2022
@elie-delorme
Copy link

This is working very well for me, very easy to use in combination with openfortivpn-webview

@DimitriPapadopoulos
Copy link
Collaborator

Can you perhaps squash the commits into a single commit, and rebase if needed? Then I can merge.

This adds two new options that allow to pass session cookies:
--cookie and --cookie-on-stdin. Such options allow to delegate
the authentication to external programs, which is mainly useful
for SAML.
@gm-vm
Copy link
Contributor Author

gm-vm commented Jun 13, 2022

Done.

@filippor
Copy link

filippor commented Apr 26, 2024

For use of external browser this repository has a script for it https://github.com/filippor/XdgOpenSaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants