auth-user-pass: add support for inline credentials

--auth-user-pass is probably the only option expecting a filename as
argument that cannot be inline'd as of today.

This patch allows specifying username and password inline in the config
file within the <auth-user-pass></auth-user-pass> tag.

This logic was already implemented for --http-proxy-user-pass, therefore
it was just about applying it to this specific option as well.
Note that the current logic expects username and password to always be
specified when inline. Therefore omitting the password will result in
storing an empty password.

A later patch will change this behaviour to make it consistent with the
classic case (username writte in file), where the password is requested
via stdin when missing.

While a it, add an empty line between prototypes in init.c to make
uncrustify happy.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20220917134832.16359-1-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25236.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Antonio Quartulli 2022-09-17 15:48:32 +02:00 committed by Gert Doering
parent f96290ff90
commit 7d48d31b82
7 changed files with 42 additions and 15 deletions

View file

@ -93,6 +93,10 @@ Session timeout
using ``--session-timeout``. This option can be configured on the server, on using ``--session-timeout``. This option can be configured on the server, on
the client or can also be pushed. the client or can also be pushed.
Inline auth username and password
Username and password can now be specified inline in the configuration file
within the <auth-user-pass></auth-user-pass> tags.
Deprecated features Deprecated features
------------------- -------------------

View file

@ -71,6 +71,7 @@ static const char *saved_pid_file_name; /* GLOBAL */
#define CF_INIT_TLS_AUTH_STANDALONE (1<<2) #define CF_INIT_TLS_AUTH_STANDALONE (1<<2)
static void do_init_first_time(struct context *c); static void do_init_first_time(struct context *c);
static bool do_deferred_p2p_ncp(struct context *c); static bool do_deferred_p2p_ncp(struct context *c);
void void
@ -595,9 +596,12 @@ init_query_passwords(const struct context *c)
if (c->options.auth_user_pass_file) if (c->options.auth_user_pass_file)
{ {
#ifdef ENABLE_MANAGEMENT #ifdef ENABLE_MANAGEMENT
auth_user_pass_setup(c->options.auth_user_pass_file, &c->options.sc_info); auth_user_pass_setup(c->options.auth_user_pass_file,
c->options.auth_user_pass_file_inline,
&c->options.sc_info);
#else #else
auth_user_pass_setup(c->options.auth_user_pass_file, NULL); auth_user_pass_setup(c->options.auth_user_pass_file,
c->options.auth_user_pass_file_inline, NULL);
#endif #endif
} }
} }
@ -3080,6 +3084,7 @@ do_init_crypto_tls(struct context *c, const unsigned int flags)
to.client_config_dir_exclusive = options->client_config_dir; to.client_config_dir_exclusive = options->client_config_dir;
} }
to.auth_user_pass_file = options->auth_user_pass_file; to.auth_user_pass_file = options->auth_user_pass_file;
to.auth_user_pass_file_inline = options->auth_user_pass_file_inline;
to.auth_token_generate = options->auth_token_generate; to.auth_token_generate = options->auth_token_generate;
to.auth_token_lifetime = options->auth_token_lifetime; to.auth_token_lifetime = options->auth_token_lifetime;
to.auth_token_call_auth = options->auth_token_call_auth; to.auth_token_call_auth = options->auth_token_call_auth;

View file

@ -1562,7 +1562,7 @@ show_p2mp_parms(const struct options *o)
SHOW_BOOL(client); SHOW_BOOL(client);
SHOW_BOOL(pull); SHOW_BOOL(pull);
SHOW_STR(auth_user_pass_file); SHOW_STR_INLINE(auth_user_pass_file);
gc_free(&gc); gc_free(&gc);
} }
@ -4046,9 +4046,10 @@ options_postprocess_filechecks(struct options *options)
options->management_user_pass, R_OK, options->management_user_pass, R_OK,
"--management user/password file"); "--management user/password file");
#endif /* ENABLE_MANAGEMENT */ #endif /* ENABLE_MANAGEMENT */
errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE, errs |= check_file_access_inline(options->auth_user_pass_file_inline,
options->auth_user_pass_file, R_OK, CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
"--auth-user-pass"); options->auth_user_pass_file, R_OK,
"--auth-user-pass");
/* ** System related ** */ /* ** System related ** */
errs |= check_file_access(CHKACC_FILE, options->chroot_dir, errs |= check_file_access(CHKACC_FILE, options->chroot_dir,
R_OK|X_OK, "--chroot directory"); R_OK|X_OK, "--chroot directory");
@ -7727,10 +7728,11 @@ add_option(struct options *options,
} }
else if (streq(p[0], "auth-user-pass") && !p[2]) else if (streq(p[0], "auth-user-pass") && !p[2])
{ {
VERIFY_PERMISSION(OPT_P_GENERAL); VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INLINE);
if (p[1]) if (p[1])
{ {
options->auth_user_pass_file = p[1]; options->auth_user_pass_file = p[1];
options->auth_user_pass_file_inline = is_inline;
} }
else else
{ {

View file

@ -532,6 +532,7 @@ struct options
int push_continuation; int push_continuation;
unsigned int push_option_types_found; unsigned int push_option_types_found;
const char *auth_user_pass_file; const char *auth_user_pass_file;
bool auth_user_pass_file_inline;
struct options_pre_connect *pre_connect; struct options_pre_connect *pre_connect;
int scheduled_exit_interval; int scheduled_exit_interval;

View file

@ -395,23 +395,32 @@ static char *auth_challenge; /* GLOBAL */
#endif #endif
void void
auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sci) auth_user_pass_setup(const char *auth_file, bool is_inline,
const struct static_challenge_info *sci)
{ {
unsigned int flags = GET_USER_PASS_MANAGEMENT;
if (is_inline)
{
flags |= GET_USER_PASS_INLINE_CREDS;
}
auth_user_pass_enabled = true; auth_user_pass_enabled = true;
if (!auth_user_pass.defined && !auth_token.defined) if (!auth_user_pass.defined && !auth_token.defined)
{ {
#ifdef ENABLE_MANAGEMENT #ifdef ENABLE_MANAGEMENT
if (auth_challenge) /* dynamic challenge/response */ if (auth_challenge) /* dynamic challenge/response */
{ {
flags |= GET_USER_PASS_DYNAMIC_CHALLENGE;
get_user_pass_cr(&auth_user_pass, get_user_pass_cr(&auth_user_pass,
auth_file, auth_file,
UP_TYPE_AUTH, UP_TYPE_AUTH,
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_DYNAMIC_CHALLENGE, flags,
auth_challenge); auth_challenge);
} }
else if (sci) /* static challenge response */ else if (sci) /* static challenge response */
{ {
int flags = GET_USER_PASS_MANAGEMENT|GET_USER_PASS_STATIC_CHALLENGE; flags |= GET_USER_PASS_STATIC_CHALLENGE;
if (sci->flags & SC_ECHO) if (sci->flags & SC_ECHO)
{ {
flags |= GET_USER_PASS_STATIC_CHALLENGE_ECHO; flags |= GET_USER_PASS_STATIC_CHALLENGE_ECHO;
@ -424,7 +433,7 @@ auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *
} }
else else
#endif /* ifdef ENABLE_MANAGEMENT */ #endif /* ifdef ENABLE_MANAGEMENT */
get_user_pass(&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT); get_user_pass(&auth_user_pass, auth_file, UP_TYPE_AUTH, flags);
} }
} }
@ -2139,9 +2148,12 @@ key_method_2_write(struct buffer *buf, struct tls_multi *multi, struct tls_sessi
if (auth_user_pass_enabled || (auth_token.token_defined && auth_token.defined)) if (auth_user_pass_enabled || (auth_token.token_defined && auth_token.defined))
{ {
#ifdef ENABLE_MANAGEMENT #ifdef ENABLE_MANAGEMENT
auth_user_pass_setup(session->opt->auth_user_pass_file, session->opt->sci); auth_user_pass_setup(session->opt->auth_user_pass_file,
session->opt->auth_user_pass_file_inline,
session->opt->sci);
#else #else
auth_user_pass_setup(session->opt->auth_user_pass_file, NULL); auth_user_pass_setup(session->opt->auth_user_pass_file,
session->opt->auth_user_pass_file_inline, NULL);
#endif #endif
struct user_pass *up = &auth_user_pass; struct user_pass *up = &auth_user_pass;

View file

@ -373,9 +373,11 @@ void pem_password_setup(const char *auth_file);
/* /*
* Setup authentication username and password. If auth_file is given, use the * Setup authentication username and password. If auth_file is given, use the
* credentials stored in the file. * credentials stored in the file, however, if is_inline is true then auth_file
* contains the username/password inline.
*/ */
void auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sc_info); void auth_user_pass_setup(const char *auth_file, bool is_inline,
const struct static_challenge_info *sc_info);
/* /*
* Ensure that no caching is performed on authentication information * Ensure that no caching is performed on authentication information

View file

@ -367,6 +367,7 @@ struct tls_options
bool auth_user_pass_verify_script_via_file; bool auth_user_pass_verify_script_via_file;
const char *tmp_dir; const char *tmp_dir;
const char *auth_user_pass_file; const char *auth_user_pass_file;
bool auth_user_pass_file_inline;
bool auth_token_generate; /**< Generate auth-tokens on successful bool auth_token_generate; /**< Generate auth-tokens on successful
* user/pass auth,seet via * user/pass auth,seet via