44#ifdef ENABLE_CRYPTO_OPENSSL
75 for (
int i = 0; i <
TM_SIZE; ++i)
77 for (
int j = 0; j <
KS_SIZE; ++j)
110 const char *ret = NULL;
115 if (ret && strlen(ret))
155 msg(
D_TLS_ERRORS,
"TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled",
174 const char *ret = NULL;
179 if (ret && strlen(ret))
203 if (!
session->cert_hash_set->ch[error_depth])
255 else if (!chs1 && !chs2)
325 const char *subject,
const char *common_name)
337 msg(
D_HANDSHAKE,
"VERIFY nsCertType ERROR: %s, require nsCertType=%s",
419 snprintf(envname,
sizeof(envname),
"tls_id_%d", cert_depth);
495 cert_depth, subject);
500 cert_depth, subject);
512 int cert_depth,
char *subject)
532 cert_depth, subject);
537 cert_depth, subject);
546 const char *subject,
int cert_depth)
556 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial number is not available",
557 cert_depth, subject);
561 if (!snprintf(fn,
sizeof(fn),
"%s%c%s", crl_dir,
PATH_SEPARATOR, serial))
569 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial=%s is revoked",
570 cert_depth, subject, serial);
593 const char *pem_export_fname = NULL;
605 "subject string from certificate", cert_depth);
625 "subject string ('%s') -- note that the field length is "
626 "limited to %d characters",
639 "certificate -- note that the username length is "
640 "limited to %d characters",
649 char *common_name =
BSTR(&buf);
653 "username string from certificate",
cert_depth);
687 msg(
M_WARN,
"Unexpected invalid algorithm used with "
698 BLEN(&cert_fp)) == 0)
702 current_hash = current_hash->
next;
710 "certificate hash verification failed. (got certificate "
711 "fingerprint: %s)", hex_fp);
729 if (!pem_export_fname
757 opt->
es, cert_depth, subject))
810 if (client_reason && strlen(client_reason))
816#ifdef ENABLE_MANAGEMENT
862 const char *client_method = strtok(iv_sso,
",");
863 bool supported =
false;
865 while (client_method)
867 if (0 == strcmp(client_method, method))
872 client_method = strtok(NULL,
",");
897 if (lines && lines->
head)
903 msg(
M_WARN,
"auth pending control file is not at least "
904 "three lines long.");
920 msg(
M_WARN,
"could not parse auth pending file timeout");
930 "Authentication failed, required pending auth "
933 msg(
M_INFO,
"Client does not supported auth pending method "
957 if (
ads->auth_control_file)
960 free(
ads->auth_control_file);
963 if (
ads->auth_failed_reason_file)
966 free(
ads->auth_failed_reason_file);
967 ads->auth_failed_reason_file =
NULL;
1001 return (acf && apf);
1040 if (
ads->auth_control_file)
1042 unsigned int ret =
ads->auth_control_status;
1058 ads->auth_control_status = ret;
1087#ifdef ENABLE_MANAGEMENT
1126static time_t cache_intervals[] = {0, 0, 0, 0, 0, 1, 1, 2, 2, 4, 8};
1187 dmsg(
D_TLS_ERRORS,
"TAS: a=%d s=%d d=%d f=%d", active, success, deferred, failed_auth);
1218 else if (active == 0 || deferred)
1232#ifdef ENABLE_MANAGEMENT
1294 const char *tmp_file =
"";
1304 if (
session->opt->auth_user_pass_verify_script_via_file)
1317 msg(
D_TLS_ERRORS,
"TLS Auth Error: could not write username/password to file: %s",
1335 "could not create deferred auth control file", __func__);
1342 "--auth-user-pass-verify");
1375 if (!
session->opt->auth_user_pass_verify_script_via_file)
1381 if (tmp_file && strlen(tmp_file) > 0)
1412 if (!
session->opt->client_crresponse_script)
1424 static const char *openerrmsg =
"TLS CR Response Error: could not write "
1425 "crtext challenge response to file: %s";
1476 "could not create deferred auth control file", __func__);
1510#ifdef ENABLE_MANAGEMENT
1515#define KMDA_SUCCESS 1
1578 "TLS Auth Error: --username-as-common name specified and "
1579 "username is longer than the maximum permitted Common Name "
1603#ifdef ENABLE_MANAGEMENT
1620 bool skip_auth =
false;
1627 msg(
D_MULTI_LOW,
"TLS: Replacing client provided username '%s' with "
1628 "username from override-user '%s'", up->
username,
1651 if (
session->opt->auth_token_call_auth)
1665 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1666 "succeeded for username '%s'",
1674 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1675 "failed for username '%s'", up->
username);
1692#ifdef ENABLE_MANAGEMENT
1703 if (
session->opt->auth_user_pass_verify_script)
1735#ifdef ENABLE_MANAGEMENT
1753 if ((
session->opt->auth_token_generate))
1775 msg(
D_HANDSHAKE,
"TLS: Username/Password authentication %s for username '%s' %s",
1783 msg(
D_TLS_ERRORS,
"TLS Auth Error: Auth Username/Password verification failed for peer");
1801 const char *cn =
session->common_name;
1804 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled",
1820 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth",
1833 const char *cn =
session->common_name;
1840 msg(
D_TLS_ERRORS,
"TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
1842 path ? path :
"UNDEF");
1857 && 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)
#define ENABLE_MANAGEMENT
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)
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
#define OPENVPN_PLUGIN_TLS_VERIFY
#define OPENVPN_PLUGIN_FUNC_DEFERRED
#define OPENVPN_PLUGIN_FUNC_SUCCESS
#define OPENVPN_PLUGIN_FUNC_ERROR
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.
bool ssl_verify_username_length(struct tls_session *session, const char *username)
Checks if the username length is valid to use.
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.
void set_common_name(struct tls_session *session, const char *common_name)
Sets the common name 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)
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 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 TLS_USERNAME_LEN
Maximum length of common name.
#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)
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.
char * peer_info
A multi-line string of general-purpose info received from peer over control channel.
char * locked_username
The locked username is the username we assume the client is using.
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 * locked_cn
Our locked common name, username, and cert hashes (cannot change during the life of this tls_multi ob...
char * client_reason
An error message to send to client on AUTH_FAILED.
char * auth_token
If server sends a generated auth-token, this is the token to use for future user/pass authentications...
char * locked_original_username
The username that client initially used before being overridden by –override-user.
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)