Go to the documentation of this file.
43 #ifdef ENABLE_CRYPTO_OPENSSL
51 #define TLS_USERNAME_LEN 64
77 for (
int i = 0; i <
TM_SIZE; ++i)
79 for (
int j = 0; j <
KS_SIZE; ++j)
115 const char *ret = NULL;
120 if (ret && strlen(ret))
157 msg(
D_TLS_ERRORS,
"TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled",
179 const char *ret = NULL;
184 if (ret && strlen(ret))
208 if (!
session->cert_hash_set->ch[error_depth])
260 else if (!chs1 && !chs2)
330 const char *subject,
const char *common_name)
342 msg(
D_HANDSHAKE,
"VERIFY nsCertType ERROR: %s, require nsCertType=%s",
406 const char *subject,
const char *common_name,
424 snprintf(envname,
sizeof(envname),
"tls_id_%d", cert_depth);
429 snprintf(envname,
sizeof(envname),
"tls_common_name_%d", cert_depth);
438 snprintf(envname,
sizeof(envname),
"tls_digest_%d", cert_depth);
442 snprintf(envname,
sizeof(envname),
"tls_digest_sha256_%d",
450 snprintf(envname,
sizeof(envname),
"tls_serial_%d", cert_depth);
455 snprintf(envname,
sizeof(envname),
"tls_serial_hex_%d", cert_depth);
467 const char *pem_export_fname)
479 if (pem_export_fname)
481 unlink(pem_export_fname);
506 cert_depth, subject);
511 cert_depth, subject);
543 cert_depth, subject);
548 cert_depth, subject);
557 const char *subject,
int cert_depth)
567 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial number is not available",
568 cert_depth, subject);
572 if (!snprintf(fn,
sizeof(fn),
"%s%c%s", crl_dir,
PATH_SEPARATOR, serial))
580 msg(
D_HANDSHAKE,
"VERIFY CRL: depth=%d, %s, serial=%s is revoked",
581 cert_depth, subject, serial);
604 const char *pem_export_fname = NULL;
616 "subject string from certificate", cert_depth);
636 "subject string ('%s') -- note that the field length is "
637 "limited to %d characters",
645 if (!
buf_printf(&buf, i ?
"_%s" :
"%s", username))
650 "certificate -- note that the username length is "
651 "limited to %d characters",
660 char *common_name =
BSTR(&buf);
664 "username string from certificate", cert_depth);
680 struct buffer cert_fp = {0};
698 msg(
M_WARN,
"Unexpected invalid algorithm used with "
709 BLEN(&cert_fp)) == 0)
713 current_hash = current_hash->
next;
721 "certificate hash verification failed. (got certificate "
722 "fingerprint: %s)", hex_fp);
740 if (!pem_export_fname
769 opt->
es, cert_depth, cert, subject))
822 if (client_reason && strlen(client_reason))
828 #ifdef ENABLE_MANAGEMENT
874 const char *client_method = strtok(iv_sso,
",");
875 bool supported =
false;
877 while (client_method)
879 if (0 == strcmp(client_method, method))
884 client_method = strtok(NULL,
",");
909 if (lines && lines->
head)
915 msg(
M_WARN,
"auth pending control file is not at least "
916 "three lines long.");
929 long timeout = strtol(
BSTR(timeout_buf), NULL, 10);
932 msg(
M_WARN,
"could not parse auth pending file timeout");
937 const char *pending_method =
BSTR(iv_buf);
941 snprintf(buf,
sizeof(buf),
942 "Authentication failed, required pending auth "
943 "method '%s' not supported", pending_method);
945 msg(
M_INFO,
"Client does not supported auth pending method "
946 "'%s'", pending_method);
1013 return (acf && apf);
1032 ret =
BSTR(&reason);
1061 const int c = fgetc(fp);
1100 #ifdef ENABLE_MANAGEMENT
1103 ASSERT(auth_plugin < 4 && auth_script < 4 && auth_man < 4);
1139 static time_t
cache_intervals[] = {0, 0, 0, 0, 0, 1, 1, 2, 2, 4, 8};
1156 bool deferred =
false;
1159 bool success =
false;
1165 bool failed_auth =
false;
1200 dmsg(
D_TLS_ERRORS,
"TAS: a=%d s=%d d=%d f=%d", active, success, deferred, failed_auth);
1231 else if (active == 0 || deferred)
1245 #ifdef ENABLE_MANAGEMENT
1307 const char *tmp_file =
"";
1317 if (
session->opt->auth_user_pass_verify_script_via_file)
1330 msg(
D_TLS_ERRORS,
"TLS Auth Error: could not write username/password to file: %s",
1348 "could not create deferred auth control file", __func__);
1355 "--auth-user-pass-verify");
1388 if (!
session->opt->auth_user_pass_verify_script_via_file)
1394 if (tmp_file && strlen(tmp_file) > 0)
1405 #ifdef ENABLE_PLUGIN
1425 if (!
session->opt->client_crresponse_script)
1437 static const char *openerrmsg =
"TLS CR Response Error: could not write "
1438 "crtext challenge response to file: %s";
1489 "could not create deferred auth control file", __func__);
1523 #ifdef ENABLE_MANAGEMENT
1527 #define KMDA_ERROR 0
1528 #define KMDA_SUCCESS 1
1529 #define KMDA_UNDEF 2
1597 #ifdef ENABLE_MANAGEMENT
1614 bool skip_auth =
false;
1634 if (
session->opt->auth_token_call_auth)
1648 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1649 "succeeded for username '%s'",
1657 msg(
M_WARN,
"TLS: Username/auth-token authentication "
1658 "failed for username '%s'", up->
username);
1675 #ifdef ENABLE_MANAGEMENT
1686 if (
session->opt->auth_user_pass_verify_script)
1697 "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters",
1721 #ifdef ENABLE_MANAGEMENT
1739 if ((
session->opt->auth_token_generate))
1761 msg(
D_HANDSHAKE,
"TLS: Username/Password authentication %s for username '%s' %s",
1769 msg(
D_TLS_ERRORS,
"TLS Auth Error: Auth Username/Password verification failed for peer");
1787 const char *cn =
session->common_name;
1790 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled",
1806 msg(
D_TLS_ERRORS,
"TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth",
1819 const char *cn =
session->common_name;
1826 msg(
D_TLS_ERRORS,
"TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
1828 path ? path :
"UNDEF");
1843 && 0 == strncmp(
"X509_", item->
string, strlen(
"X509_")))
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
char * auth_failed_reason_file
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 * auth_token
If server sends a generated auth-token, this is the token to use for future user/pass authentications...
result_t x509_verify_cert_eku(openvpn_x509_cert_t *x509, const char *const expected_oid)
#define MAX_CERT_DEPTH
Maximum certificate depth we will allow.
static unsigned int min_uint(unsigned int x, unsigned int y)
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...
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)
unsigned int auth_token_state_flags
The state of the auth-token sent from the client.
struct cert_hash_set * cert_hash_set
const char * verify_x509_name
void verify_crresponse_script(struct tls_multi *multi, const char *cr_response)
Runs the –client-crresponse script if one is defined.
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)
unsigned int auth_control_status
static struct gc_arena gc_new(void)
#define VERIFY_X509_SUBJECT_RDN_PREFIX
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...
#define VERIFY_X509_SUBJECT_DN
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA256 fingerprint.
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.
static bool is_auth_token(const char *password)
Return if the password string has the format of a password.
#define TM_SIZE
Size of the tls_multi.session array.
#define TLS_AUTHENTICATED(multi, ks)
Check whether the ks key_state has finished the key exchange part of the OpenVPN hand shake.
#define KS_PRIMARY
Primary key state index.
#define VERIFY_X509_SUBJECT_RDN
struct cert_hash_set * locked_cert_hash_set
struct cert_hash * ch[MAX_CERT_DEPTH]
Array of certificate hashes.
struct tls_session session[TM_SIZE]
Array of tls_session objects representing control channel sessions with the remote peer.
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
struct verify_hash_list * next
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.
char username[USER_PASS_LEN]
#define SSLF_USERNAME_AS_COMMON_NAME
unsigned int tas_cache_num_updates
The number of times we updated the cache.
unsigned char sha256_hash[256/8]
int capacity
Size in bytes of memory allocated by malloc().
@ TLS_AUTHENTICATION_SUCCEEDED
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
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 argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
#define CC_CRLF
carriage return or newline
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
result_t backend_x509_get_username(char *common_name, int cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
const char * remote_cert_eku
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,...
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, openvpn_x509_cert_t *x509)
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.
@ KS_AUTH_FALSE
Key state is not authenticated
#define ENABLE_MANAGEMENT
result_t
Result of verification function.
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.
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
#define SSLF_AUTH_USER_PASS_OPTIONAL
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.
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
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...
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
#define STATUS_OUTPUT_WRITE
Security parameter state for a single VPN tunnel.
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 void key_state_rm_auth_pending_file(struct auth_deferred_status *ads)
Removes auth_pending file from the file system and key_state structure.
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
enum ks_auth_state authenticated
static result_t verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert, const char *subject, const char *common_name)
Security parameter state of one TLS and data channel key session.
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 const char * np(const char *str)
static int plugin_call(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es)
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
static result_t verify_cert_call_command(const char *verify_command, struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert, char *subject)
#define TM_ACTIVE
Active tls_session.
result_t x509_verify_cert_ku(openvpn_x509_cert_t *x509, const unsigned *const expected_ku, int expected_len)
char * string_alloc(const char *str, struct gc_arena *gc)
void string_replace_leading(char *str, const char match, const char replace)
const char * tls_username(const struct tls_multi *multi, const bool null)
Returns the username field for the given tunnel.
void buf_chomp(struct buffer *buf)
void tls_x509_clear_env(struct env_set *es)
Remove any X509_ env variables from env_set es.
enum auth_deferred_result mda_status
#define OPENVPN_PLUGIN_FUNC_ERROR
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.
struct verify_hash_list * verify_hash
const struct x509_track * x509_track
void tls_lock_common_name(struct tls_multi *multi)
Locks the common name field for the given tunnel.
const char * export_peer_cert_dir
#define ALLOC_OBJ(dptr, type)
#define CC_PRINT
printable (>= 32, != 127)
struct key_state key[KS_SIZE]
#define SSLF_CRL_VERIFY_DIR
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.
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_entry * next
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)
#define OPENVPN_PLUGIN_FUNC_DEFERRED
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.
void verify_crresponse_plugin(struct tls_multi *multi, const char *cr_response)
Call the plugin OPENVPN_PLUGIN_CLIENT_CRRESPONSE.
static void tls_deauthenticate(struct tls_multi *multi)
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate's SHA1 fingerprint.
void status_printf(struct status_output *so, const char *format,...)
static int verify_user_pass_script(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
@ TLS_AUTHENTICATION_FAILED
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
const char * verify_command
static bool set_verify_user_pass_env(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
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.
#define TLS_USERNAME_LEN
Maximum length of common name.
#define OPENVPN_PLUGIN_TLS_VERIFY
static char * key_state_check_auth_failed_message_file(const struct auth_deferred_status *ads, struct tls_multi *multi, struct gc_arena *gc)
Checks if the auth failed reason file has any content and if yes it will be returned as string alloca...
static void string_mod_remap_name(char *str)
static bool tls_lock_username(struct tls_multi *multi, const char *username)
@ KS_AUTH_TRUE
Key state is authenticated.
static bool management_enable_def_auth(const struct management *man)
Wrapper structure for dynamically allocated memory.
@ ACF_SUCCEEDED
deferred auth has suceeded
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
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_lock_cert_hash_set(struct tls_multi *multi)
Locks the certificate hash set used in the given tunnel.
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_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth, const char *subject, const char *common_name, const struct x509_track *x509_track)
char * x509_username_field[2]
uint8_t hash[SHA256_DIGEST_LENGTH]
Security parameter state of a single session within a VPN tunnel.
void generate_auth_token(const struct user_pass *up, struct tls_multi *multi)
Generate an auth token based on username and timestamp.
static int verify_user_pass_plugin(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
bool status_close(struct status_output *so)
static void setenv_untrusted(struct tls_session *session)
hash_algo_type verify_hash_algo
Structure containing the hashes for a full certificate chain.
Garbage collection arena used to keep track of dynamically allocated memory.
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.
void setenv_str(struct env_set *es, const char *name, const char *value)
bool env_set_del(struct env_set *es, const char *str)
struct auth_deferred_status plugin_auth
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
#define AUTH_TOKEN_HMAC_OK
Auth-token sent from client has valid hmac.
#define S_EXITCODE
Instead of returning 1/0 for success/fail, return exit code when between 0 and 255 and -1 otherwise.
static enum auth_deferred_result man_def_auth_test(const struct key_state *ks)
@ ACF_PENDING
deferred auth still pending
static struct cert_hash_set * cert_hash_copy(const struct cert_hash_set *chs)
struct auth_deferred_status script_auth
static int max_int(int x, int y)
#define AUTH_TOKEN_EXPIRED
Auth-token sent from client has expired.
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage)
void cert_hash_free(struct cert_hash_set *chs)
Frees the given set of certificate hashes.
static SERVICE_STATUS status
void auth_set_client_reason(struct tls_multi *multi, const char *client_reason)
Sets the reason why authentication of a client failed.
static void gc_free(struct gc_arena *a)
@ ACF_FAILED
deferred auth has failed
Structure containing the hash for a single certificate.
@ KS_AUTH_DEFERRED
Key state authentication is being deferred, by async auth.
#define ALLOC_OBJ_CLEAR(dptr, type)
static int verify_user_pass_management(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
static result_t verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert, const char *subject, int cert_depth)
void wipe_auth_token(struct tls_multi *multi)
Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
static void verify_cert_cert_delete_env(struct env_set *es, const char *pem_export_fname)
time_t auth_deferred_expire
time_t tas_cache_last_update
Time of last when we updated the cached state of tls_authentication_status deferred files.
#define OPENVPN_PLUGIN_FUNC_SUCCESS
static time_t cache_intervals[]
The minimum times to have passed to update the cache.
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
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.
static const char * print_nsCertType(int type)
unsigned remote_cert_ku[MAX_PARMS]
char password[USER_PASS_LEN]
bool plugin_defined(const struct plugin_list *pl, const int type)
static void set_common_name(struct tls_session *session, const char *common_name)
void setenv_link_socket_actual(struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, const unsigned int flags)
char * auth_token_initial
The first auth-token we sent to a client.
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...
#define KS_SIZE
Size of the tls_session.key array.
void setenv_del(struct env_set *es, const char *name)
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
@ ACF_DISABLED
deferred auth is not used
void verify_user_pass(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Main username/password verification entry point.
void tls_clear_error(void)
Clear the underlying SSL library's error state.
bool buf_printf(struct buffer *buf, const char *format,...)
struct buffer_entry * head
@ TLS_AUTHENTICATION_DEFERRED
const struct plugin_list * plugins
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
const char * tls_common_name(const struct tls_multi *multi, const bool null)
Returns the common name field for the given tunnel.
static int cleanup(void **state)