Hi Davide, I had some time today, so I did some changes ("improvements", I hope ;-)) to your code:
First thing you do in add_option() if inline is used: auth_pass_file is set (to "stdin"). So there is no need to check for both (options->auth_user_pass_file || options->auth_user_pass_file_inline), the "existing" check only for "options->auth_user_pass_file" will suffice. That simplifies the patch. Fixed terminating the copy of the strings. Simplify tests in options_postprocess_verify_ce(): Fist check if options->auth_user_pass_file is set (as above, it is "allways" set in any auth_user_path case), then it is always safe to do "streq" on options->auth_user_pass_file, too. Use existing file_check for inline files "CHKACC_INLINE" in options_postprocess_filechecks() In auth_user_pass_setup() don't change indents, only add "extra_flags" Kind regards Joerg -------- Original-Nachricht -------- Betreff: Re: [Openvpn-devel] [PATCH] Allow inlining of --auth-user-pass Von: Davide Brini <dave...@gmx.com> An: max.mus...@kaffeeschluerfer.com Kopie (CC): openvpn-devel@lists.sourceforge.net Datum: So 06 Okt 2013 21:01:04 CEST > Thanks for reporting! I have poor connectivity and little time this week, but > I will look at it when I have a chance. > > Sent from mobile > > max.mus...@kaffeeschluerfer.com wrote: [... snip ...]
--- src/openvpn/init.c +++ src/openvpn/init.c @@ -401,9 +401,9 @@ if (c->options.auth_user_pass_file) { #ifdef ENABLE_CLIENT_CR - 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 - 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 --- src/openvpn/misc.c +++ src/openvpn/misc.c @@ -1044,7 +1044,7 @@ if (!up->defined) { - const bool from_stdin = (!auth_file || !strcmp (auth_file, "stdin")); + const bool from_stdin = (!auth_file || streq (auth_file, "stdin")); if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) msg (M_WARN, "Note: previous '%s' credentials failed", prefix); --- src/openvpn/options.c +++ src/openvpn/options.c @@ -1221,6 +1221,7 @@ SHOW_BOOL (client); SHOW_BOOL (pull); SHOW_STR (auth_user_pass_file); + SHOW_STR (auth_user_pass_file_inline); gc_free (&gc); } @@ -2339,6 +2340,42 @@ #if P2MP if (options->auth_user_pass_file && !options->pull) msg (M_USAGE, "--auth-user-pass requires --pull"); + if (options->auth_user_pass_file) /* no check needed if no auth_pass_file set. It is even set in case of inline (to "stdin") */ + { + if ( (!streq(options->auth_user_pass_file, "stdin") || options->auth_user_pass_file_inline) && options->auth_nocache) + msg (M_USAGE, "Cannot use --auth-nocache with credentials from file"); +#ifdef ENABLE_CLIENT_CR + if ( (!streq(options->auth_user_pass_file, "stdin") || options->auth_user_pass_file_inline) && options->sc_info.challenge_text) + msg (M_USAGE, "Credentials cannot be in a file if using --static-challenge"); +#endif + } + if (options->auth_user_pass_file_inline) + { + int n_inlined = 0; + const char *pos = options->auth_user_pass_file_inline; + const char *prev = pos; + + if ( strlen(pos) == 0 ) + msg (M_USAGE, "Invalid format for inlined --auth-user-pass"); + + while( (pos = strchr(pos, '\n')) != NULL ) + { + n_inlined++; + + if (n_inlined > 2) + msg (M_USAGE, "Too many lines in inlined --auth-user-pass"); + + if ( pos - prev > USER_PASS_LEN - 1 ) + msg (M_USAGE, "Line too long in inlined --auth-user-pass"); + + pos++; + prev = pos; + } + + if ( (n_inlined == 0) || (*prev != '\0') ) + msg (M_USAGE, "Invalid format for inlined --auth-user-pass"); + + } #endif uninit_options (&defaults); @@ -2706,7 +2743,7 @@ "--management user/password file"); #endif /* ENABLE_MANAGEMENT */ #if P2MP - errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN, + errs |= check_file_access (CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_INLINE, options->auth_user_pass_file, R_OK, "--auth-user-pass"); #endif /* P2MP */ @@ -5835,7 +5872,12 @@ VERIFY_PERMISSION (OPT_P_GENERAL); if (p[1]) { - options->auth_user_pass_file = p[1]; + options->auth_user_pass_file = p[1]; + if (streq (p[1], INLINE_FILE_TAG) && p[2]) + { msg (M_WARN, "options.c \n !!!SETTING !!! \n_ +5930,12 @@ add_optio"); + options->auth_user_pass_file = "stdin"; + options->auth_user_pass_file_inline = p[2]; + } } else options->auth_user_pass_file = "stdin"; @@ -6462,6 +6504,7 @@ else if (streq (p[0], "auth-nocache")) { VERIFY_PERMISSION (OPT_P_GENERAL); + options->auth_nocache = true; ssl_set_auth_nocache (); } else if (streq (p[0], "auth-token") && p[1]) --- src/openvpn/options.h +++ src/openvpn/options.h @@ -290,6 +290,7 @@ bool up_delay; bool up_restart; bool daemon; + bool auth_nocache; int remap_sigusr1; @@ -459,6 +460,7 @@ bool pull; /* client pull of config options from server */ int push_continuation; const char *auth_user_pass_file; + const char *auth_user_pass_file_inline; struct options_pre_pull *pre_pull; int server_poll_timeout; --- src/openvpn/ssl.c +++ src/openvpn/ssl.c @@ -357,11 +357,57 @@ #endif void -auth_user_pass_setup (const char *auth_file, const struct static_challenge_info *sci) +auth_user_pass_setup (const char *auth_file, const char *auth_file_inline, const struct static_challenge_info *sci) { + + int extra_flags = 0; + int n_inlined = 0; + char inlined_username[USER_PASS_LEN]; + char inlined_password[USER_PASS_LEN]; + auth_user_pass_enabled = true; + if (!auth_user_pass.defined) { + if (auth_file && streq (auth_file, "stdin") && auth_file_inline) + { + /* check how much is inlined. */ + const char *pos = auth_file_inline; + const char *prev = pos; + + while( (pos = strchr(pos, '\n')) != NULL) + { + n_inlined++; + + if (n_inlined == 1) + { + strncpy(inlined_username, prev, pos - prev); + inlined_username[pos - prev] = '\0'; + msg (M_INFO, "Using inlined username: %s", inlined_username); + } + else + { + strncpy(inlined_password, prev, pos - prev); + inlined_password[pos - prev] = '\0'; + msg (M_INFO, "Using inlined password: ... "); + } + + pos++; + prev = pos; + } + + if (n_inlined == 1) + extra_flags = GET_USER_PASS_PASSWORD_ONLY; + } + + if (n_inlined == 2) + { + strcpy(auth_user_pass.username, inlined_username); + strcpy(auth_user_pass.password, inlined_password); + auth_user_pass.defined = true; + } + else + { #if AUTO_USERID get_user_pass_auto_userid (&auth_user_pass, auth_file); #else @@ -370,11 +416,11 @@ get_user_pass_cr (&auth_user_pass, auth_file, UP_TYPE_AUTH, - GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_DYNAMIC_CHALLENGE, + GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_DYNAMIC_CHALLENGE|extra_flags, auth_challenge); else if (sci) /* static challenge response */ { - int flags = GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_STATIC_CHALLENGE; + int flags = GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_STATIC_CHALLENGE|extra_flags; if (sci->flags & SC_ECHO) flags |= GET_USER_PASS_STATIC_CHALLENGE_ECHO; get_user_pass_cr (&auth_user_pass, @@ -385,8 +431,11 @@ } else # endif - get_user_pass (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE); + get_user_pass (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|extra_flags); #endif + } + if (n_inlined == 1) + strcpy(auth_user_pass.username, inlined_username); } } @@ -1872,9 +1921,9 @@ if (auth_user_pass_enabled) { #ifdef ENABLE_CLIENT_CR - auth_user_pass_setup (NULL, session->opt->sci); + auth_user_pass_setup (NULL, NULL, session->opt->sci); #else - auth_user_pass_setup (NULL, NULL); + auth_user_pass_setup (NULL, NULL, NULL); #endif if (!write_string (buf, auth_user_pass.username, -1)) goto error; --- src/openvpn/ssl.h +++ src/openvpn/ssl.h @@ -388,7 +388,7 @@ * Setup authentication username and password. If auth_file is given, use the * credentials stored in the file. */ -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, const char *auth_file_inline, const struct static_challenge_info *sc_info); /* * Ensure that no caching is performed on authentication information