diff options
Diffstat (limited to 'src/openvpn/ssl_verify.c')
-rw-r--r-- | src/openvpn/ssl_verify.c | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 33115eb..4f3b61d 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -5,8 +5,8 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net> - * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com> + * Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net> + * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -906,6 +906,39 @@ key_state_test_auth_control_file(struct key_state *ks) #endif /* ifdef PLUGIN_DEF_AUTH */ +/* This function is called when a session's primary key state first becomes KS_TRUE */ +void ssl_session_fully_authenticated(struct tls_multi *multi, struct tls_session* session) +{ + struct key_state *ks = &session->key[KS_PRIMARY]; + if (ks->key_id == 0) + { + /* A key id of 0 indicates a new session and the client will + * get the auth-token as part of the initial push reply */ + return; + } + + /* + * Auth token already sent to client, update auth-token on client. + * The initial auth-token is sent as part of the push message, for this + * update we need to schedule an extra push message. + * + * Otherwise the auth-token get pushed out as part of the "normal" + * push-reply + */ + if (multi->auth_token_initial) + { + /* + * We do not explicitly schedule the sending of the + * control message here but control message are only + * postponed when the control channel is not yet fully + * established and furthermore since this is called in + * the middle of authentication, there are other messages + * (new data channel keys) that are sent anyway and will + * trigger scheduling + */ + send_push_reply_auth_token(multi); + } +} /* * Return current session authentication state. Return * value is TLS_AUTHENTICATION_x. @@ -975,6 +1008,12 @@ tls_authentication_status(struct tls_multi *multi, const int latency) case ACF_SUCCEEDED: case ACF_DISABLED: success = true; + /* i=0 is the TM_ACTIVE/KS_PRIMARY session */ + if (i == 0 && ks->authenticated == KS_AUTH_DEFERRED) + { + ssl_session_fully_authenticated(multi, + &multi->session[TM_ACTIVE]); + } ks->authenticated = KS_AUTH_TRUE; break; @@ -1269,7 +1308,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, */ if (session->opt->auth_token_generate && is_auth_token(up->password)) { - multi->auth_token_state_flags = verify_auth_token(up, multi, session); + ks->auth_token_state_flags = verify_auth_token(up, multi, session); if (session->opt->auth_token_call_auth) { /* @@ -1278,7 +1317,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, * decide what to do with the result */ } - else if (multi->auth_token_state_flags == AUTH_TOKEN_HMAC_OK) + else if (ks->auth_token_state_flags == AUTH_TOKEN_HMAC_OK) { /* * We do not want the EXPIRED or EMPTY USER flags here so check @@ -1373,8 +1412,8 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, * the initial timestamp and session id can be extracted from it */ if (!multi->auth_token - && (multi->auth_token_state_flags & AUTH_TOKEN_HMAC_OK) - && !(multi->auth_token_state_flags & AUTH_TOKEN_EXPIRED)) + && (ks->auth_token_state_flags & AUTH_TOKEN_HMAC_OK) + && !(ks->auth_token_state_flags & AUTH_TOKEN_EXPIRED)) { multi->auth_token = strdup(up->password); } @@ -1385,31 +1424,14 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, */ generate_auth_token(up, multi); } - /* - * Auth token already sent to client, update auth-token on client. - * The initial auth-token is sent as part of the push message, for this - * update we need to schedule an extra push message. - * - * Otherwise the auth-token get pushed out as part of the "normal" - * push-reply - */ - if (multi->auth_token_initial) - { - /* - * We do not explicitly schedule the sending of the - * control message here but control message are only - * postponed when the control channel is not yet fully - * established and furthermore since this is called in - * the middle of authentication, there are other messages - * (new data channel keys) that are sent anyway and will - * trigger schedueling - */ - send_push_reply_auth_token(multi); - } msg(D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", (ks->authenticated == KS_AUTH_DEFERRED) ? "deferred" : "succeeded", up->username, (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : ""); + if (ks->authenticated == KS_AUTH_TRUE) + { + ssl_session_fully_authenticated(multi, session); + } } else { |