Some GlobalProtect portals do not use SAML at all. Instead of opening a
browser, the portal answers the prelogin request with a standard login
challenge and gpclient asks for the credentials interactively on its
terminal, for example:
Please enter RSA token (Portal: vpn.example.com)
? Username:
? Passcode:
After the portal phase, the gateway may run a second authentication round (e.g. domain username + Active Directory password) and MFA challenges (one-time codes) can appear as well.
Historically the NetworkManager service spawned gpclient without a
terminal, so those prompts could never be displayed or answered and the
connection hung until it was disconnected
(issue #6).
The service runs gpclient under a pseudo-terminal (PTY) and watches its
output:
- Authentication banners (
Please enter RSA token (Portal: ...)) are parsed to know which server/phase is asking. - When an interactive prompt is detected, the service answers it:
- Username — from
vpn.datakeyusername(also passed togpclient --user, so usually the prompt never appears), otherwise the user is asked. - Password — from the
passwordsecret stored in the connection, otherwise the user is asked. - One-time secrets (labels/banners mentioning token, OTP, passcode, PIN, code, RSA...) — the user is always asked; a stored password is never reused for these.
- Username — from
- "Asking the user" uses the standard NetworkManager interactive secrets
flow: the service emits the
SecretsRequiredD-Bus signal, the desktop applet shows a dialog (the plugin ships an auth dialog for GNOME/nm-applet), and the answer comes back viaNewSecrets.
Because a stored password is only used once per connection attempt, a two-phase flow like portal: RSA token → gateway: AD password works: the token is asked interactively, the AD password can come from the stored secret (or is asked as well).
Store the username; the token (and any second-phase password, unless stored) will be asked in a dialog on every connect:
nmcli connection modify "My VPN" +vpn.data username=jdoeOptionally also store the second-phase (gateway/AD) password:
nmcli connection modify "My VPN" +vpn.secrets password=SuperSecretFully non-interactive setup — ask NetworkManager to collect and store the password upfront:
nmcli connection modify "My VPN" +vpn.data username=jdoe
nmcli connection modify "My VPN" +vpn.data auth-mode=credentials
nmcli connection modify "My VPN" +vpn.secrets password=SuperSecretWith auth-mode=credentials the service reports to NetworkManager that the
vpn setting needs secrets before connecting, so GUI applets will prompt for
(and can save) the password like for any other VPN type. Without it the
password is only requested mid-connection when gpclient actually asks.
Nothing changes — auth-mode defaults to saml and authentication happens
in the browser as before.
A portal usually offers several gateways and gpclient asks which one to use,
again on its terminal:
? Which gateway do you want to connect to?
> gw-warsaw (gw1.example.com)
gw-frankfurt (gw2.example.com)
[↑↓ to move, enter to select, type to filter]
The service answers this without asking the user:
- With
preferred-gatewayset invpn.data, the matching entry is selected. The value is matched against the whole entry, then the name and the host part, then as a substring - so bothgw-frankfurtandgw2.example.comwork. - With no
preferred-gateway(the default), the portal's first proposal wins. gpclient sorts the list by region, so this is the gateway it would have picked itself. - If a configured gateway is not offered any more, the first proposal is used and a warning is logged. The setting is left untouched - the portal may just have changed temporarily.
After a successful connection the discovered list is cached in the profile
(vpn.data gateway-list, entries separated by ;), and the connection editors
offer it as a drop-down for Preferred gateway. The first entry of that
drop-down, First proposed by portal (automatic), stores nothing.
# Pick a specific gateway from the command line
nmcli connection modify "My VPN" +vpn.data preferred-gateway="gw-frankfurt"
# Back to automatic
nmcli connection modify "My VPN" -vpn.data preferred-gateway
# See what the last successful connection discovered
nmcli -g vpn.data connection show "My VPN"--gateway is deliberately never passed to gpclient: it makes gpclient abort
with Cannot find gateway specified when the value is unknown, which would
remove any chance of falling back
(issue #7).
The address in the connection is normally a portal. If your organisation
gave you a gateway address instead, tick Address is a gateway (skip the
portal) (vpn.data as-gateway=true) - otherwise the portal workflow is tried
first and you may end up authenticating twice. When gpclient itself notices
this, the service logs a hint saying so.
Some portals authenticate you twice, which means two browser windows in a row:
gpauth started <- portal authentication
Connecting to the selected gateway: gw1.example.com (gw1.example.com)
GP response error: ... respMsg = "Authentication failure: Invalid username or password"
Gateway login failed: Gateway login error: <none>
Performing the gateway authentication...
gpauth started <- and again, for the gateway
Nothing is wrong with the credentials. gpclient first tries to log in to the chosen gateway with the authentication cookie it got from the portal; when the gateway refuses that cookie, it falls back to a full gateway authentication, which opens a second browser window. This is gpclient's behaviour, not the plugin's.
If the address in your connection is itself one of the gateways the portal
offers (compare it with the cached gateway-list), you can skip the portal
round entirely and get a single authentication:
nmcli connection modify "My VPN" +vpn.data as-gateway=trueThe trade-off is that you no longer pick between gateways - you always connect to the address in the connection.
- GNOME / nm-applet: the plugin installs
/usr/libexec/nm-gpclient-auth-dialogand declaressupports-hints=true, so both upfront and mid-connection (RSA token/OTP) prompts show a GTK dialog. - KDE Plasma: plasma-nm shows its own generic VPN secrets dialog for interactive requests.
- nmcli: activate with
nmcli --ask connection up "My VPN"so nmcli can ask for secrets on the terminal, or store all secrets in the connection. Without any way to ask, the service fails the connection with a clear login error instead of hanging.
The user has 300 s to answer an interactive secrets request; afterwards the
connection fails with LOGIN_FAILED.
The browser window for SAML authentication has its own, separate timeout
(GP_AUTH_TIMEOUT, 300 s by default) - see
EDGE_WRAPPER.md.