44#ifdef ENABLE_CRYPTO_OPENSSL
52#define TLS_USERNAME_LEN 64
78 for (
int i = 0; i <
TM_SIZE; ++i)
80 for (
int j = 0; j <
KS_SIZE; ++j)
116 const char *ret = NULL;
121 if (ret && strlen(ret))
158 msg(
D_TLS_ERRORS,
"TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled",
177 const char *ret = NULL;
182 if (ret && strlen(ret))
206 if (!
session->cert_hash_set->ch[error_depth])
258 else if (!chs1 && !chs2)
328 const char *subject,
const char *common_name)
340 msg(
D_HANDSHAKE,
"VERIFY nsCertType ERROR: %s, require nsCertType=%s",
422 snprintf(envname,
sizeof(envname),
"tls_id_%d", cert_depth);
495 if (ret == OPENVPN_PLUGIN_FUNC_SUCCESS)
498 cert_depth, subject);
503 cert_depth, subject);
515 int cert_depth,
char *subject)
535 cert_depth, subject);
540 cert_depth, subject);
549 const char *subject,
int cert_depth)
559 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial number is not available",
560 cert_depth, subject);
564 if (!snprintf(fn,
sizeof(fn),
"%s%c%s", crl_dir,
PATH_SEPARATOR, serial))
572 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial=%s is revoked",
573 cert_depth, subject, serial);
596 const char *pem_export_fname = NULL;
608 "subject string from certificate", cert_depth);
628 "subject string ('%s') -- note that the field length is "
629 "limited to %d characters",
642 "certificate -- note that the username length is "
643 "limited to %d characters",
652 char *common_name =
BSTR(&buf);
656 "username string from certificate",
cert_depth);
690 msg(
M_WARN,
"Unexpected invalid algorithm used with "
701 BLEN(&cert_fp)) == 0)
705 current_hash = current_hash->
next;
713 "certificate hash verification failed. (got certificate "
714 "fingerprint: %s)", hex_fp);
732 if (!pem_export_fname
760 opt->
es, cert_depth, subject))
813 if (client_reason && strlen(client_reason))
819#ifdef ENABLE_MANAGEMENT
865 const char *client_method = strtok(iv_sso,
",");
866 bool supported =
false;
868 while (client_method)
870 if (0 == strcmp(client_method, method))
875 client_method = strtok(NULL,
",");
900 if (lines && lines->
head)
906 msg(
M_WARN,
"auth pending control file is not at least "
907 "three lines long.");
923 msg(
M_WARN,
"could not parse auth pending file timeout");
933 "Authentication failed, required pending auth "
936 msg(
M_INFO,
"Client does not supported auth pending method "
960 if (
ads->auth_control_file)
963 free(
ads->auth_control_file);
966 if (
ads->auth_failed_reason_file)
969 free(
ads->auth_failed_reason_file);
970 ads->auth_failed_reason_file =
NULL;
1004 return (acf && apf);
1043 if (
ads->auth_control_file)
1045 unsigned int ret =
ads->auth_control_status;
1061 ads->auth_control_status = ret;
1090#ifdef ENABLE_MANAGEMENT
1129static time_t cache_intervals[] = {0, 0, 0, 0, 0, 1, 1, 2, 2, 4, 8};
1190 dmsg(
D_TLS_ERRORS,
"TAS: a=%d s=%d d=%d f=%d", active, success, deferred, failed_auth);
1221 else if (active == 0 || deferred)
1235#ifdef ENABLE_MANAGEMENT
1297 const char *tmp_file =
"";
1298 int retval = OPENVPN_PLUGIN_FUNC_ERROR;
1307 if (
session->opt->auth_user_pass_verify_script_via_file)
1320 msg(
D_TLS_ERRORS,
"TLS Auth Error: could not write username/password to file: %s",
1338 "could not create deferred auth control file", __func__);
1339 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1345 "--auth-user-pass-verify");
1349 retval = OPENVPN_PLUGIN_FUNC_SUCCESS;
1353 retval = OPENVPN_PLUGIN_FUNC_DEFERRED;
1358 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1361 if (retval == OPENVPN_PLUGIN_FUNC_DEFERRED)
1368 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1378 if (!
session->opt->auth_user_pass_verify_script_via_file)
1384 if (tmp_file && strlen(tmp_file) > 0)
1415 if (!
session->opt->client_crresponse_script)
1427 static const char *openerrmsg =
"TLS CR Response Error: could not write "
1428 "crtext challenge response to file: %s";
1469 int retval = OPENVPN_PLUGIN_FUNC_ERROR;
1479 "could not create deferred auth control file", __func__);
1486 if (retval == OPENVPN_PLUGIN_FUNC_DEFERRED)
1492 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1496 if (retval == OPENVPN_PLUGIN_FUNC_ERROR)
1501 if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED)
1513#ifdef ENABLE_MANAGEMENT
1518#define KMDA_SUCCESS 1
1588#ifdef ENABLE_MANAGEMENT
1605 bool skip_auth =
false;
1625 if (
session->opt->auth_token_call_auth)
1639 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1640 "succeeded for username '%s'",
1648 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1649 "failed for username '%s'", up->
username);
1654 int plugin_status = OPENVPN_PLUGIN_FUNC_SUCCESS;
1655 int script_status = OPENVPN_PLUGIN_FUNC_SUCCESS;
1660 plugin_status = OPENVPN_PLUGIN_FUNC_ERROR;
1666#ifdef ENABLE_MANAGEMENT
1677 if (
session->opt->auth_user_pass_verify_script)
1688 "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters",
1690 plugin_status = OPENVPN_PLUGIN_FUNC_ERROR;
1691 script_status = OPENVPN_PLUGIN_FUNC_ERROR;
1694 bool plugin_ok = plugin_status == OPENVPN_PLUGIN_FUNC_SUCCESS
1695 || plugin_status == OPENVPN_PLUGIN_FUNC_DEFERRED;
1697 bool script_ok = script_status == OPENVPN_PLUGIN_FUNC_SUCCESS
1698 || script_status == OPENVPN_PLUGIN_FUNC_DEFERRED;
1701#ifdef ENABLE_MANAGEMENT
1707 if (plugin_status == OPENVPN_PLUGIN_FUNC_DEFERRED
1708 || script_status == OPENVPN_PLUGIN_FUNC_DEFERRED)
1712#ifdef ENABLE_MANAGEMENT
1730 if ((
session->opt->auth_token_generate))
1752 msg(
D_HANDSHAKE,
"TLS: Username/Password authentication %s for username '%s' %s",
1760 msg(
D_TLS_ERRORS,
"TLS Auth Error: Auth Username/Password verification failed for peer");
1778 const char *cn =
session->common_name;
1781 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled",
1797 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth",
1810 const char *cn =
session->common_name;
1817 msg(
D_TLS_ERRORS,
"TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
1819 path ? path :
"UNDEF");
1834 && 0 == strncmp(
"X509_", item->
string, strlen(
"X509_")))
void argv_msg_prefix(const int msglev, const struct argv *a, const char *prefix)
Similar to argv_msg() but prefixes the messages being written with a given string.
void argv_parse_cmd(struct argv *argres, const char *cmdstr)
Parses a command string, tokenizes it and puts each element into a separate struct argv argument slot...
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
void generate_auth_token(const struct user_pass *up, struct tls_multi *multi)
Generate an auth token based on username and timestamp.
unsigned int verify_auth_token(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Verifies the auth token to be in the format that generate_auth_token create and checks if the token i...
void add_session_token_env(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
Put the session id, and auth token status into the environment if auth-token is enabled.
void wipe_auth_token(struct tls_multi *multi)
Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.
static bool is_auth_token(const char *password)
Return if the password string has the format of a password.
bool buf_printf(struct buffer *buf, const char *format,...)
void string_replace_leading(char *str, const char match, const char replace)
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc)
buffer_read_from_file - copy the content of a file into a buffer
char * string_alloc(const char *str, struct gc_arena *gc)
void buf_chomp(struct buffer *buf)
#define ALLOC_OBJ(dptr, type)
#define CC_CRLF
carriage return or newline
static void gc_free(struct gc_arena *a)
#define CC_PRINT
printable (>= 32, != 127)
#define ALLOC_OBJ_CLEAR(dptr, type)
static struct gc_arena gc_new(void)
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
void setenv_str(struct env_set *es, const char *name, const char *value)
bool env_set_del(struct env_set *es, const char *str)
void setenv_del(struct env_set *es, const char *name)
#define KS_SIZE
Size of the tls_session.key array.
#define KS_PRIMARY
Primary key state index.
#define TM_SIZE
Size of the tls_multi.session array.
#define TM_ACTIVE
Active tls_session.
#define TLS_AUTHENTICATED(multi, ks)
Check whether the ks key_state has finished the key exchange part of the OpenVPN hand shake.
static unsigned int min_uint(unsigned int x, unsigned int y)
static int max_int(int x, int y)
static SERVICE_STATUS status
void management_notify_client_needing_auth(struct management *management, const unsigned int mda_key_id, struct man_def_auth_context *mdac, const struct env_set *es)
static bool management_enable_def_auth(const struct management *man)
int plugin_call_ssl(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es, int certdepth, openvpn_x509_cert_t *current_cert)
bool plugin_defined(const struct plugin_list *pl, const int type)
static int plugin_call(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es)
bool send_auth_pending_messages(struct tls_multi *tls_multi, struct tls_session *session, const char *extra, unsigned int timeout)
Sends the auth pending control messages to a client.
#define S_EXITCODE
Instead of returning 1/0 for success/fail, return exit code when between 0 and 255 and -1 otherwise.
static int openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook)
Will run a script and return the exit code of the script if between 0 and 255, -1 otherwise.
void setenv_link_socket_actual(struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, const unsigned int flags)
void tls_clear_error(void)
Clear the underlying SSL library's error state.
#define AUTH_TOKEN_HMAC_OK
Auth-token sent from client has valid hmac.
@ ACF_PENDING
deferred auth still pending
@ ACF_SUCCEEDED
deferred auth has suceeded
@ ACF_FAILED
deferred auth has failed
@ ACF_DISABLED
deferred auth is not used
#define AUTH_TOKEN_EXPIRED
Auth-token sent from client has expired.
static struct key_state * get_key_scan(struct tls_multi *multi, int index)
gets an item of key_state objects in the order they should be scanned by data channel modules.
#define SSLF_AUTH_USER_PASS_OPTIONAL
@ KS_AUTH_TRUE
Key state is authenticated.
@ KS_AUTH_FALSE
Key state is not authenticated
@ KS_AUTH_DEFERRED
Key state authentication is being deferred, by async auth.
#define SSLF_CRL_VERIFY_DIR
static const struct key_state * get_primary_key(const struct tls_multi *multi)
gets an item of key_state objects in the order they should be scanned by data channel modules.
#define SSLF_USERNAME_AS_COMMON_NAME
char * extract_var_peer_info(const char *peer_info, const char *var, struct gc_arena *gc)
Extracts a variable from peer info, the returned string will be allocated using the supplied gc_arena...
static result_t verify_cert_call_command(const char *verify_command, struct env_set *es, int cert_depth, char *subject)
static void verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth, const char *subject, const struct x509_track *x509_track)
void key_state_rm_auth_control_files(struct auth_deferred_status *ads)
Removes auth_pending and auth_control files from file system and key_state structure.
static bool key_state_gen_auth_control_files(struct auth_deferred_status *ads, const struct tls_options *opt)
Generates and creates the control files used for deferred authentification in the temporary directory...
static struct cert_hash_set * cert_hash_copy(const struct cert_hash_set *chs)
static void key_state_rm_auth_pending_file(struct auth_deferred_status *ads)
Removes auth_pending file from the file system and key_state structure.
static result_t verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert, const char *subject, int cert_depth)
bool tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason)
static void verify_cert_cert_delete_env(struct env_set *es, const char *pem_export_fname)
static void tls_deauthenticate(struct tls_multi *multi)
void verify_crresponse_plugin(struct tls_multi *multi, const char *cr_response)
Call the plugin OPENVPN_PLUGIN_CLIENT_CRRESPONSE.
bool cert_hash_compare(const struct cert_hash_set *chs1, const struct cert_hash_set *chs2)
Compares certificates hashes, returns true if hashes are equal.
void tls_x509_clear_env(struct env_set *es)
Remove any X509_ env variables from env_set es.
static void update_key_auth_status(bool cached, struct key_state *ks)
This method takes a key_state and if updates the state of the key if it is deferred.
void tls_lock_cert_hash_set(struct tls_multi *multi)
Locks the certificate hash set used in the given tunnel.
static result_t verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert, const char *subject, const char *common_name)
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
void tls_lock_common_name(struct tls_multi *multi)
Locks the common name field for the given tunnel.
static enum auth_deferred_result man_def_auth_test(const struct key_state *ks)
void verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session)
Perform final authentication checks, including locking of the cn, the allowed certificate hashes,...
static bool tls_lock_username(struct tls_multi *multi, const char *username)
static int verify_user_pass_plugin(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
static bool key_state_check_auth_pending_file(struct auth_deferred_status *ads, struct tls_multi *multi, struct tls_session *session)
Checks if the deferred state should also send auth pending request to the client.
const char * tls_username(const struct tls_multi *multi, const bool null)
Returns the username field for the given tunnel.
static char * key_state_check_auth_failed_message_file(const struct auth_deferred_status *ads, struct gc_arena *gc)
Checks if the auth failed reason file has any content and if yes it will be returned as string alloca...
void auth_set_client_reason(struct tls_multi *multi, const char *client_reason)
Sets the reason why authentication of a client failed.
static result_t verify_cert_call_plugin(const struct plugin_list *plugins, struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert, char *subject)
#define TLS_USERNAME_LEN
Maximum length of common name.
enum tls_auth_status tls_authentication_status(struct tls_multi *multi)
Return current session authentication state of the tls_multi structure This will return TLS_AUTHENTIC...
void verify_user_pass(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Main username/password verification entry point.
static bool tls_authentication_status_use_cache(struct tls_multi *multi)
uses cache_intervals times to determine if we should update the cache.
static void check_for_client_reason(struct tls_multi *multi, struct auth_deferred_status *status)
Check if the script/plugin left a message in the auth failed message file and relay it to the user.
static const char * print_nsCertType(int type)
void verify_crresponse_script(struct tls_multi *multi, const char *cr_response)
Runs the –client-crresponse script if one is defined.
static time_t cache_intervals[]
The minimum times to have passed to update the cache.
static int verify_user_pass_script(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
static enum auth_deferred_result key_state_test_auth_control_file(struct auth_deferred_status *ads, bool cached)
Checks the auth control status from a file.
static void string_mod_remap_name(char *str)
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
static void setenv_untrusted(struct tls_session *session)
const char * tls_common_name(const struct tls_multi *multi, const bool null)
Returns the common name field for the given tunnel.
static int verify_user_pass_management(struct tls_session *session, const struct user_pass *up)
static void set_common_name(struct tls_session *session, const char *common_name)
static bool verify_cert_cert_export_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, const char *pem_export_fname)
Exports the certificate in peer_cert into the environment and adds the filname.
void cert_hash_free(struct cert_hash_set *chs)
Frees the given set of certificate hashes.
static bool check_auth_pending_method(const char *peer_info, const char *method)
Check peer_info if the client supports the requested pending auth method.
static bool set_verify_user_pass_env(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Control Channel Verification Module.
@ TLS_AUTHENTICATION_DEFERRED
@ TLS_AUTHENTICATION_SUCCEEDED
@ TLS_AUTHENTICATION_FAILED
#define VERIFY_X509_SUBJECT_DN
#define VERIFY_X509_SUBJECT_RDN
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
#define VERIFY_X509_SUBJECT_RDN_PREFIX
#define MAX_CERT_DEPTH
Maximum certificate depth we will allow.
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Control Channel Verification Module library-specific backend interface.
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA256 fingerprint.
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, openvpn_x509_cert_t *x509)
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage)
result_t backend_x509_get_username(char *common_name, int cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
result_t x509_verify_cert_ku(openvpn_x509_cert_t *x509, const unsigned *const expected_ku, int expected_len)
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA1 fingerprint.
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
result_t
Result of verification function.
result_t x509_verify_cert_eku(openvpn_x509_cert_t *x509, const char *const expected_oid)
mbedtls_x509_crt openvpn_x509_cert_t
Control Channel Verification Module OpenSSL backend.
void status_printf(struct status_output *so, const char *format,...)
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
bool status_close(struct status_output *so)
#define STATUS_OUTPUT_WRITE
char * auth_failed_reason_file
struct buffer_entry * next
struct buffer_entry * head
Wrapper structure for dynamically allocated memory.
int capacity
Size in bytes of memory allocated by malloc().
int len
Length in bytes of the actual content within the allocated memory.
Structure containing the hashes for a full certificate chain.
struct cert_hash * ch[MAX_CERT_DEPTH]
Array of certificate hashes.
Structure containing the hash for a single certificate.
unsigned char sha256_hash[256/8]
Garbage collection arena used to keep track of dynamically allocated memory.
Security parameter state of one TLS and data channel key session.
unsigned int auth_token_state_flags
The state of the auth-token sent from the client.
struct auth_deferred_status plugin_auth
struct auth_deferred_status script_auth
enum auth_deferred_result mda_status
enum ks_auth_state authenticated
time_t auth_deferred_expire
Security parameter state for a single VPN tunnel.
char * auth_token_initial
The first auth-token we sent to a client.
unsigned int tas_cache_num_updates
The number of times we updated the cache.
struct tls_session session[TM_SIZE]
Array of tls_session objects representing control channel sessions with the remote peer.
struct cert_hash_set * locked_cert_hash_set
time_t tas_cache_last_update
Time of last when we updated the cached state of tls_authentication_status deferred files.
char * auth_token
If server sends a generated auth-token, this is the token to use for future user/pass authentications...
unsigned remote_cert_ku[MAX_PARMS]
const struct plugin_list * plugins
const char * export_peer_cert_dir
const char * verify_command
struct verify_hash_list * verify_hash
char * x509_username_field[2]
const char * verify_x509_name
const struct x509_track * x509_track
hash_algo_type verify_hash_algo
const char * remote_cert_eku
Security parameter state of a single session within a VPN tunnel.
struct key_state key[KS_SIZE]
struct cert_hash_set * cert_hash_set
char password[USER_PASS_LEN]
char username[USER_PASS_LEN]
struct verify_hash_list * next
uint8_t hash[SHA256_DIGEST_LENGTH]
static int cleanup(void **state)