Skip to content

Commit

Permalink
Implement auth-token-user
Browse files Browse the repository at this point in the history
When not using username and password (i.e. auth-user-pass) it can still
be desirable to provide the client with an auth-token, e.g. for allowing
a session to continue after a reconnect without requiring 2FA again.

However, without --auth-user-pass openvpn does not have a username and will
ignore any pushed auth-token command.

This patch adds support for auth-token-user to set the username that should
be used for auth-token

The spec of using auth-token-user base64-encoded-user are the ones that
OpenVPN3 already implements.

Patch V2: Improve style, fix comments and commit message

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20210520151148.2565578-2-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22417.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit b398aa3)
  • Loading branch information
schwabe authored and cron2 committed Jun 15, 2021
1 parent 1ca147b commit d38d611
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 11 deletions.
8 changes: 8 additions & 0 deletions doc/man-sections/client-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ configuration.
after a failed auth. Older clients will keep using the token value and
react according to ``--auth-retry``

--auth-token-user base64username
Companion option to ``--auth-token``. This options allows to override
the username used by the client when reauthenticating with the ``auth-token``.
It also allows to use ``--auth-token`` in setups that normally do not use
username and password.

The username has to be base64 encoded.

--auth-user-pass
Authenticate with server using username/password.

Expand Down
37 changes: 32 additions & 5 deletions src/openvpn/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,22 +510,49 @@ void
set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token)
{

if (strlen(token) && (up->defined || tk->defined))
if (strlen(token))
{
/* auth-token has no password, so it needs the username
* either already set or copied from up */
strncpynt(tk->password, token, USER_PASS_LEN);
if (up->defined)
tk->token_defined = true;

/*
* --auth-token has no username, so it needs the username
* either already set or copied from up, or later set by
* --auth-token-user
*
* Do not overwrite the username if already set to avoid
* overwriting an username set by --auth-token-user
*/
if (up->defined && !tk->defined)
{
strncpynt(tk->username, up->username, USER_PASS_LEN);
tk->defined = true;
}
tk->defined = true;
}

/* Cleans user/pass for nocache */
purge_user_pass(up, false);
}

void
set_auth_token_user(struct user_pass *tk, const char *username)
{
if (strlen(username))
{
/* Clear the username before decoding to ensure no old material is left
* and also allow decoding to not use all space to ensure the last byte is
* always 0 */
CLEAR(tk->username);
int len = openvpn_base64_decode(username, tk->username, USER_PASS_LEN - 1);
tk->defined = len > 0;
if (!tk->defined)
{
msg(D_PUSH, "Error decoding auth-token-username");
}
}
}


/*
* Process string received by untrusted peer before
* printing to console or log file.
Expand Down
21 changes: 18 additions & 3 deletions src/openvpn/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ const char *hostname_randomize(const char *hostname, struct gc_arena *gc);
struct user_pass
{
bool defined;
/* For auth-token username and token can be set individually, so we
* use this second bool to track if the token (password) is defined */
bool token_defined;
bool nocache;

/* max length of username/password */
Expand Down Expand Up @@ -145,19 +148,31 @@ void fail_user_pass(const char *prefix,
void purge_user_pass(struct user_pass *up, const bool force);

/**
* Sets the auth-token to token if a username is available from either
* up or already present in tk. The method will also purge up if
* Sets the auth-token to token. If a username is available from
* either up or already present in tk that will be used as default
* username for the token. The method will also purge up if
* the auth-nocache option is active.
*
* @param up (non Auth-token) Username/password
* @param tk auth-token userpass to set
* @param token token to use as password for the
* @param token token to use as password for the auth-token
*
* @note all parameters to this function must not be null.
*/
void set_auth_token(struct user_pass *up, struct user_pass *tk,
const char *token);

/**
* Sets the auth-token username by base64 decoding the passed
* username
*
* @param tk auth-token userpass to set
* @param username base64 encoded username to set
*
* @note all parameters to this function must not be null.
*/
void set_auth_token_user(struct user_pass *tk, const char *username);

/*
* Process string received by untrusted peer before
* printing to console or log file.
Expand Down
5 changes: 5 additions & 0 deletions src/openvpn/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -8278,6 +8278,11 @@ add_option(struct options *options,
}
#endif
}
else if (streq(p[0], "auth-token-user") && p[1] && !p[2])
{
VERIFY_PERMISSION(OPT_P_ECHO);
ssl_set_auth_token_user(p[1]);
}
else if (streq(p[0], "single-session") && !p[1])
{
VERIFY_PERMISSION(OPT_P_GENERAL);
Expand Down
12 changes: 9 additions & 3 deletions src/openvpn/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,12 @@ ssl_set_auth_token(const char *token)
set_auth_token(&auth_user_pass, &auth_token, token);
}

void
ssl_set_auth_token_user(const char *username)
{
set_auth_token_user(&auth_token, username);
}

/*
* Cleans an auth token and checks if it was active
*/
Expand Down Expand Up @@ -2353,8 +2359,8 @@ key_method_2_write(struct buffer *buf, struct tls_multi *multi,
}
}

/* write username/password if specified */
if (auth_user_pass_enabled)
/* write username/password if specified or we are using a auth-token */
if (auth_user_pass_enabled || (auth_token.token_defined && auth_token.defined))
{
#ifdef ENABLE_MANAGEMENT
auth_user_pass_setup(session->opt->auth_user_pass_file, session->opt->sci);
Expand All @@ -2367,7 +2373,7 @@ key_method_2_write(struct buffer *buf, struct tls_multi *multi,
* If we have a valid auth-token, send that instead of real
* username/password
*/
if (auth_token.defined)
if (auth_token.token_defined && auth_token.defined)
{
up = &auth_token;
}
Expand Down
2 changes: 2 additions & 0 deletions src/openvpn/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ void ssl_purge_auth(const bool auth_user_pass_only);

void ssl_set_auth_token(const char *token);

void ssl_set_auth_token_user(const char *username);

bool ssl_clean_auth_token(void);

#ifdef ENABLE_MANAGEMENT
Expand Down

0 comments on commit d38d611

Please sign in to comment.