Skip to content
Permalink
Browse files
Add support to OpenConnect client to use RFC6750 style Bearer tokens …
…to authenticate to the server.

Resolves: #99

Signed-off-by: Alan TG Jowett <alan.jowett@microsoft.com>
  • Loading branch information
Alan-Jowett committed Mar 10, 2020
1 parent 8820105 commit aa8d434da9ab1d645fdc14bb2c9dee545637b703
Showing with 120 additions and 6 deletions.
  1. +4 −2 Makefile.am
  2. +28 −0 http-auth.c
  3. +3 −0 library.c
  4. +17 −2 main.c
  5. +57 −0 oidc.c
  6. +6 −1 openconnect-internal.h
  7. +4 −1 openconnect.8.in
  8. +1 −0 openconnect.h
@@ -33,9 +33,10 @@ lib_srcs_juniper = oncp.c lzo.c auth-juniper.c
lib_srcs_pulse = pulse.c
lib_srcs_globalprotect = gpst.c auth-globalprotect.c
lib_srcs_oath = oath.c
lib_srcs_oidc = oidc.c

library_srcs += $(lib_srcs_juniper) $(lib_srcs_cisco) $(lib_srcs_oath) \
$(lib_srcs_globalprotect) $(lib_srcs_pulse)
$(lib_srcs_globalprotect) $(lib_srcs_pulse) $(lib_srcs_oidc)

lib_srcs_gnutls = gnutls.c gnutls_tpm.c gnutls_tpm2.c
lib_srcs_openssl = openssl.c openssl-pkcs11.c
@@ -52,7 +53,7 @@ POTFILES = $(openconnect_SOURCES) gnutls-esp.c gnutls-dtls.c openssl-esp.c opens
$(lib_srcs_esp) $(lib_srcs_dtls) gnutls_tpm2_esys.c gnutls_tpm2_ibm.c \
$(lib_srcs_openssl) $(lib_srcs_gnutls) $(library_srcs) \
$(lib_srcs_win32) $(lib_srcs_posix) $(lib_srcs_gssapi) $(lib_srcs_iconv) \
$(lib_srcs_yubikey) $(lib_srcs_stoken)
$(lib_srcs_yubikey) $(lib_srcs_stoken) $(lib_srcs_oidc)

if OPENCONNECT_LIBPCSCLITE
library_srcs += $(lib_srcs_yubikey)
@@ -98,6 +99,7 @@ else
library_srcs += $(lib_srcs_posix)
endif


libopenconnect_la_SOURCES = version.c $(library_srcs)
libopenconnect_la_CFLAGS = $(AM_CFLAGS) $(SSL_CFLAGS) $(DTLS_SSL_CFLAGS) $(LIBXML2_CFLAGS) $(LIBPROXY_CFLAGS) $(ZLIB_CFLAGS) $(P11KIT_CFLAGS) $(TSS_CFLAGS) $(LIBSTOKEN_CFLAGS) $(LIBPSKC_CFLAGS) $(GSSAPI_CFLAGS) $(INTL_CFLAGS) $(ICONV_CFLAGS) $(LIBPCSCLITE_CFLAGS) $(LIBP11_CFLAGS) $(LIBLZ4_CFLAGS)
libopenconnect_la_LIBADD = $(SSL_LIBS) $(DTLS_SSL_LIBS) $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(ZLIB_LIBS) $(P11KIT_LIBS) $(TSS_LIBS) $(LIBSTOKEN_LIBS) $(LIBPSKC_LIBS) $(GSSAPI_LIBS) $(INTL_LIBS) $(ICONV_LIBS) $(LIBPCSCLITE_LIBS) $(LIBP11_LIBS) $(LIBLZ4_LIBS)
@@ -190,6 +190,33 @@ static int basic_authorization(struct openconnect_info *vpninfo, int proxy,
return 0;
}

static int bearer_authorization(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state,
struct oc_text_buf *hdrbuf)
{
const char *bearer_token = vpninfo->bearer_token;

if (proxy) {
return -EINVAL;
}

if (!bearer_token)
return -EINVAL;

if (auth_state->state == AUTH_IN_PROGRESS) {
auth_state->state = AUTH_FAILED;
return -EAGAIN;
}

buf_append(hdrbuf, "Authorization: Bearer %s\r\n", bearer_token);

vpn_progress(vpninfo, PRG_INFO, _("Attempting HTTP Bearer authentication to server '%s'\n"),
vpninfo->hostname);

auth_state->state = AUTH_IN_PROGRESS;
return 0;
}

#if !defined(HAVE_GSSAPI) && !defined(_WIN32)
static int no_gssapi_authorization(struct openconnect_info *vpninfo, int proxy,
struct http_auth_state *auth_state,
@@ -215,6 +242,7 @@ struct auth_method {
{ AUTH_TYPE_NTLM, "NTLM", ntlm_authorization, cleanup_ntlm_auth },
{ AUTH_TYPE_DIGEST, "Digest", digest_authorization, NULL },
{ AUTH_TYPE_BASIC, "Basic", basic_authorization, NULL },
{ AUTH_TYPE_BEARER, "Bearer", bearer_authorization, NULL },
#if !defined(HAVE_GSSAPI) && !defined(_WIN32)
{ AUTH_TYPE_GSSAPI, "Negotiate", no_gssapi_authorization, NULL }
#endif
@@ -482,6 +482,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
free(vpninfo->tun_pkt);
free(vpninfo->dtls_pkt);
free(vpninfo->cstp_pkt);
free(vpninfo->bearer_token);
free(vpninfo);
}

@@ -886,6 +887,8 @@ int openconnect_set_token_mode(struct openconnect_info *vpninfo,
case OC_TOKEN_MODE_YUBIOATH:
return set_yubikey_mode(vpninfo, token_str);
#endif
case OC_TOKEN_MODE_OIDC:
return set_oidc_token(vpninfo, token_str);
default:
return -EOPNOTSUPP;
}
19 main.c
@@ -812,8 +812,8 @@ static void usage(void)
printf(" -g, --usergroup=GROUP %s\n", _("Set login usergroup"));
printf(" -p, --key-password=PASS %s\n", _("Set key passphrase or TPM SRK PIN"));
printf(" --key-password-from-fsid %s\n", _("Key passphrase is fsid of file system"));
printf(" --token-mode=MODE %s\n", _("Software token type: rsa, totp or hotp"));
printf(" --token-secret=STRING %s\n", _("Software token secret"));
printf(" --token-mode=MODE %s\n", _("Software token type: rsa, totp, hotp or oidc"));
printf(" --token-secret=STRING %s\n", _("Software token secret or oidc token"));
#ifndef HAVE_LIBSTOKEN
printf(" %s\n", _("(NOTE: libstoken (RSA SecurID) disabled in this build)"));
#endif
@@ -1459,6 +1459,8 @@ int main(int argc, char **argv)
token_mode = OC_TOKEN_MODE_HOTP;
} else if (strcasecmp(config_arg, "yubioath") == 0) {
token_mode = OC_TOKEN_MODE_YUBIOATH;
} else if (strcasecmp(config_arg, "oidc") == 0) {
token_mode = OC_TOKEN_MODE_OIDC;
} else {
fprintf(stderr, _("Invalid software token mode \"%s\"\n"),
config_arg);
@@ -2252,6 +2254,19 @@ static void init_token(struct openconnect_info *vpninfo,
exit(1);
}

case OC_TOKEN_MODE_OIDC:
switch (ret) {
case 0:
return;
case -ENOENT:
fprintf(stderr, _("Can't open oidc file\n"));
exit(1);
default:
fprintf(stderr, _("General failure in oidc token\n"));
exit(1);
}

break;
case OC_TOKEN_MODE_NONE:
/* No-op */
break;
57 oidc.c
@@ -0,0 +1,57 @@
/*
* OpenConnect (SSL + DTLS) VPN client
*
* Copyright © 2008-2015 Microsoft Corp
*
* Author: Alan Jowett <alan.jowett@microsoft.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/

#include <config.h>

#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "openconnect-internal.h"

int set_oidc_token(struct openconnect_info *vpninfo, const char *token_str)
{
int ret;
char *file_token = NULL;

if (token_str) {
switch(token_str[0]) {
case '@':
token_str++;
/* fall through */
case '/':
ret = openconnect_read_file(vpninfo, token_str, &file_token);
if (ret < 0)
return ret;
}
}

if (!file_token) {
vpninfo->bearer_token = strdup(token_str);
if (!vpninfo->bearer_token) {
return 1;
}
}
else {
vpninfo->bearer_token = file_token;
}
vpninfo->token_mode = OC_TOKEN_MODE_OIDC;
return 0;
}


@@ -223,8 +223,9 @@ struct oc_text_buf {
#define AUTH_TYPE_NTLM 1
#define AUTH_TYPE_DIGEST 2
#define AUTH_TYPE_BASIC 3
#define AUTH_TYPE_BEARER 4

#define MAX_AUTH_TYPES 4
#define MAX_AUTH_TYPES 5

#define AUTH_DEFAULT_DISABLED -3
#define AUTH_DISABLED -2
@@ -419,6 +420,7 @@ struct openconnect_info {
int proxy_fd;
char *proxy_user;
char *proxy_pass;
char *bearer_token;
int proxy_close_during_auth;
int retry_on_auth_fail;
int try_http_auth;
@@ -1046,6 +1048,9 @@ int do_gen_hotp_code(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt);

int set_oidc_token(struct openconnect_info *vpninfo,
const char *token_str);

/* stoken.c */
int prepare_stoken(struct openconnect_info *vpninfo);
int set_libstoken_mode(struct openconnect_info *vpninfo, const char *token_str);
@@ -472,7 +472,8 @@ will call liboath to generate an RFC 6238 time-based password, and
.B \-\-token\-mode=hotp
will call liboath to generate an RFC 4226 HMAC-based password. Yubikey
tokens which generate OATH codes in hardware are supported with
.B \-\-token\-mode=yubioath
.B \-\-token\-mode=yubioath. \-\-token\-mode=oidc will use the provided
OpenIDConnect token as an RFC 6750 bearer token.
.TP
.B \-\-token\-secret={ SECRET[,COUNTER] | @FILENAME }
The secret to use when generating one-time passwords/verification codes.
@@ -487,6 +488,8 @@ For Yubikey OATH the token secret specifies the name of the credential to be
used. If not provided, the first OATH credential found on the device will be
used.

For OIDC the secret is the bearer token to be used.

.IR FILENAME ,
if specified, can contain any of the above strings. Or, it can contain a
SecurID XML (SDTID) seed.
@@ -345,6 +345,7 @@ typedef enum {
OC_TOKEN_MODE_TOTP,
OC_TOKEN_MODE_HOTP,
OC_TOKEN_MODE_YUBIOATH,
OC_TOKEN_MODE_OIDC,
} oc_token_mode_t;

typedef enum {

0 comments on commit aa8d434

Please sign in to comment.