From ea85d97bd56086bcf7f700b12a24734ed4d70460 Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Wed, 18 Sep 2019 08:30:39 +0200 Subject: [PATCH] Add --askpin option Adding --askpin option modeled after --askpass, letting people enter pin early int he startup or more importantly allow them to keep a password in separate file to simplify unattended setup. Signed-off-by: Michal Hrusecky --- doc/openvpn.8 | 3 +++ src/openvpn/init.c | 7 +++++++ src/openvpn/options.c | 19 +++++++++++++++++++ src/openvpn/options.h | 3 +++ src/openvpn/pkcs11.c | 20 +++++++++++++++++++- 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 4185ffed6dc..6c062443e18 100644 --- a/doc/openvpn.8 +++ b/doc/openvpn.8 @@ -4804,6 +4804,9 @@ or options are specified without .B \-\-pkcs11\-provider being given. +.B \-\-askpin [file] +option is used to tell OpenVPN to ask for the pin phrase right a way +or to read it from file. .\"********************************************************* .TP .B \-\-pkcs11\-private\-mode mode... diff --git a/src/openvpn/init.c b/src/openvpn/init.c index b5a034dcef5..36950205304 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -546,6 +546,13 @@ init_query_passwords(const struct context *c) auth_user_pass_setup(c->options.auth_user_pass_file, NULL); #endif } +#ifdef ENABLE_PKCS11 + /* SMART Card PIN input */ + if (c->options.key_pin_file) + { + pkcs11_password_setup(c->options.key_pin_file); + } +#endif #endif } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 2d3865a6084..c8af204e2f6 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -688,6 +688,7 @@ static const char usage_message[] = " cache until token is removed.\n" "--pkcs11-id-management : Acquire identity from management interface.\n" "--pkcs11-id serialized-id 'id' : Identity to use, get using standalone --show-pkcs11-ids\n" + "--askpin [file] : Get PIN from controlling tty before we daemonize.\n" #endif /* ENABLE_PKCS11 */ "\n" "SSL Library information:\n" @@ -3329,6 +3330,10 @@ options_postprocess_filechecks(struct options *options) /* ** Password files ** */ errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE, options->key_pass_file, R_OK, "--askpass"); +#ifdef ENABLE_PKCS11 + errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE, + options->key_pin_file, R_OK, "--askpin"); +#endif #ifdef ENABLE_MANAGEMENT errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE, options->management_user_pass, R_OK, @@ -7859,6 +7864,20 @@ add_option(struct options *options, options->key_pass_file = "stdin"; } } +#ifdef ENABLE_PKCS11 + else if (streq(p[0], "askpin") && !p[2]) + { + VERIFY_PERMISSION(OPT_P_GENERAL); + if (p[1]) + { + options->key_pin_file = p[1]; + } + else + { + options->key_pin_file = "stdin"; + } + } +#endif else if (streq(p[0], "auth-nocache") && !p[1]) { VERIFY_PERMISSION(OPT_P_GENERAL); diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 63f0f4cb5c6..6d592522602 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -206,6 +206,9 @@ struct options bool persist_config; int persist_mode; +#ifdef ENABLE_PKCS11 + const char *key_pin_file; +#endif const char *key_pass_file; bool show_ciphers; bool show_digests; diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c index d40ca458d32..408b6954d51 100644 --- a/src/openvpn/pkcs11.c +++ b/src/openvpn/pkcs11.c @@ -227,6 +227,24 @@ _pkcs11_openvpn_token_prompt( } } +struct user_pass token_pass; /* GLOBAL */ + +void pkcs11_password_setup(const char* key_pin_file) { + char prompt[1024]; + token_pass.defined = false; + token_pass.nocache = true; + + if (!strlen(token_pass.password)) + { + get_user_pass( + &token_pass, + key_pin_file, + UP_TYPE_PRIVATE_KEY, + GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY + ); + } +} + static PKCS11H_BOOL _pkcs11_openvpn_pin_prompt( @@ -238,7 +256,6 @@ _pkcs11_openvpn_pin_prompt( const size_t pin_max ) { - struct user_pass token_pass; char prompt[1024]; (void)global_data; @@ -253,6 +270,7 @@ _pkcs11_openvpn_pin_prompt( token_pass.nocache = true; if ( + !strlen(token_pass.password) && !get_user_pass( &token_pass, NULL,