From 01ee1f5a41ce87efa7a4fb1ca49dbd9c3a8119e1 Mon Sep 17 00:00:00 2001 From: James Yonan Date: Tue, 6 Feb 2018 14:12:58 -0700 Subject: [PATCH] Added ClientAPI::Config::retryOnAuthFailed parameter // If true, consider AUTH_FAILED to be a non-fatal error, // and retry the connection after a pause. bool retryOnAuthFailed = false; Signed-off-by: James Yonan --- client/ovpncli.cpp | 3 +++ client/ovpncli.hpp | 4 ++++ openvpn/client/cliconnect.hpp | 6 +++++- openvpn/client/cliopt.hpp | 10 +++++++++- test/ovpncli/cli.cpp | 9 ++++++++- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/client/ovpncli.cpp b/client/ovpncli.cpp index 5892717d..191d1587 100644 --- a/client/ovpncli.cpp +++ b/client/ovpncli.cpp @@ -414,6 +414,7 @@ namespace openvpn { bool google_dns_fallback = false; bool synchronous_dns_lookup = false; bool autologin_sessions = false; + bool retry_on_auth_failed = false; std::string private_key_password; std::string external_pki_alias; bool disable_client_cert = false; @@ -654,6 +655,7 @@ namespace openvpn { state->google_dns_fallback = config.googleDnsFallback; state->synchronous_dns_lookup = config.synchronousDnsLookup; state->autologin_sessions = config.autologinSessions; + state->retry_on_auth_failed = config.retryOnAuthFailed; state->private_key_password = config.privateKeyPassword; if (!config.protoOverride.empty()) state->proto_override = Protocol::parse(config.protoOverride, Protocol::NO_SUFFIX); @@ -921,6 +923,7 @@ namespace openvpn { cc.google_dns_fallback = state->google_dns_fallback; cc.synchronous_dns_lookup = state->synchronous_dns_lookup; cc.autologin_sessions = state->autologin_sessions; + cc.retry_on_auth_failed = state->retry_on_auth_failed; cc.proto_context_options = state->proto_context_options; cc.http_proxy_options = state->http_proxy_options; cc.alt_proxy = state->alt_proxy; diff --git a/client/ovpncli.hpp b/client/ovpncli.hpp index 3059d09d..9bc21476 100644 --- a/client/ovpncli.hpp +++ b/client/ovpncli.hpp @@ -203,6 +203,10 @@ namespace openvpn { // Enable autologin sessions bool autologinSessions = true; + // If true, consider AUTH_FAILED to be a non-fatal error, + // and retry the connection after a pause. + bool retryOnAuthFailed = false; + // An ID used for get-certificate and RSA signing callbacks // for External PKI profiles. std::string externalPkiAlias; diff --git a/openvpn/client/cliconnect.hpp b/openvpn/client/cliconnect.hpp index 9bfa1e41..41851b1d 100644 --- a/openvpn/client/cliconnect.hpp +++ b/openvpn/client/cliconnect.hpp @@ -429,14 +429,18 @@ namespace openvpn { { ClientEvent::Base::Ptr ev = new ClientEvent::DynamicChallenge(reason); client_options->events().add_event(std::move(ev)); + stop(); } else { ClientEvent::Base::Ptr ev = new ClientEvent::AuthFailed(reason); client_options->events().add_event(std::move(ev)); client_options->stats().error(Error::AUTH_FAILED); + if (client_options->retry_on_auth_failed()) + queue_restart(5000); + else + stop(); } - stop(); } break; case Error::TUN_SETUP_FAILED: diff --git a/openvpn/client/cliopt.hpp b/openvpn/client/cliopt.hpp index 2919f6de..4cf41c33 100644 --- a/openvpn/client/cliopt.hpp +++ b/openvpn/client/cliopt.hpp @@ -142,6 +142,7 @@ namespace openvpn { int default_key_direction = -1; bool force_aes_cbc_ciphersuites = false; bool autologin_sessions = false; + bool retry_on_auth_failed = false; std::string tls_version_min_override; std::string tls_cert_profile_override; PeerInfo::Set::Ptr extra_peer_info; @@ -193,7 +194,8 @@ namespace openvpn { autologin_sessions(false), creds_locked(false), asio_work_always_on_(false), - synchronous_dns_lookup(false) + synchronous_dns_lookup(false), + retry_on_auth_failed_(config.retry_on_auth_failed) #ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY ,extern_transport_factory(config.extern_transport_factory) #endif @@ -548,6 +550,11 @@ namespace openvpn { return false; } + bool retry_on_auth_failed() const + { + return retry_on_auth_failed_; + } + Client::Config::Ptr client_config(const bool relay_mode) { Client::Config::Ptr cli_config = new Client::Config; @@ -836,6 +843,7 @@ namespace openvpn { bool creds_locked; bool asio_work_always_on_; bool synchronous_dns_lookup; + bool retry_on_auth_failed_; PushOptionsBase::Ptr push_base; OptionList::FilterBase::Ptr pushed_options_filter; ClientLifeCycle::Ptr client_lifecycle; diff --git a/test/ovpncli/cli.cpp b/test/ovpncli/cli.cpp index 09c271ab..b5c0abd6 100644 --- a/test/ovpncli/cli.cpp +++ b/test/ovpncli/cli.cpp @@ -543,6 +543,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) { "merge", no_argument, nullptr, 'm' }, { "version", no_argument, nullptr, 'v' }, { "auto-sess", no_argument, nullptr, 'a' }, + { "auth-retry", no_argument, nullptr, 'Y' }, { "tcprof-override", required_argument, nullptr, 'X' }, { "ssl-debug", required_argument, nullptr, 1 }, { "epki-cert", required_argument, nullptr, 2 }, @@ -588,6 +589,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) int sslDebugLevel = 0; bool googleDnsFallback = false; bool autologinSessions = false; + bool retryOnAuthFailed = false; bool tunPersist = false; bool merge = false; bool version = false; @@ -599,7 +601,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) int ch; optind = 1; - while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvau:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:X:R:", longopts, nullptr)) != -1) + while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvaYu:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:X:R:", longopts, nullptr)) != -1) { switch (ch) { @@ -693,6 +695,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) case 'a': autologinSessions = true; break; + case 'Y': + retryOnAuthFailed = true; + break; case 'j': tunPersist = true; break; @@ -786,6 +791,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) config.sslDebugLevel = sslDebugLevel; config.googleDnsFallback = googleDnsFallback; config.autologinSessions = autologinSessions; + config.retryOnAuthFailed = retryOnAuthFailed; config.tunPersist = tunPersist; config.gremlinConfig = gremlin; config.info = true; @@ -951,6 +957,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content) std::cout << "--ssl-debug : SSL debug level" << std::endl; std::cout << "--google-dns, -g : enable Google DNS fallback" << std::endl; std::cout << "--auto-sess, -a : request autologin session" << std::endl; + std::cout << "--auth-retry, -Y : retry connection on auth failure" << std::endl; std::cout << "--persist-tun, -j : keep TUN interface open across reconnects" << std::endl; std::cout << "--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,..." << std::endl; std::cout << "--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob)" << std::endl;