OpenVPN
ssl_verify.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "syshead.h"
35#include <string.h>
36
37#include "base64.h"
38#include "manage.h"
39#include "otime.h"
40#include "run_command.h"
41#include "ssl_verify.h"
42#include "ssl_verify_backend.h"
43
44#ifdef ENABLE_CRYPTO_OPENSSL
45#include "ssl_verify_openssl.h"
46#endif
47#include "auth_token.h"
48#include "push.h"
49#include "ssl_util.h"
50
52#define TLS_USERNAME_LEN 64
53
54static void
56{
57 string_mod(str, CC_PRINT, CC_CRLF, '_');
58}
59
60/*
61 * Export the untrusted IP address and port to the environment
62 */
63static void
65{
66 setenv_link_socket_actual(session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT);
67}
68
69/*
70 * Remove authenticated state from all sessions in the given tunnel
71 */
72static void
74{
75 if (multi)
76 {
77 wipe_auth_token(multi);
78 for (int i = 0; i < TM_SIZE; ++i)
79 {
80 for (int j = 0; j < KS_SIZE; ++j)
81 {
83 }
84 }
85 }
86}
87
88/*
89 * Set the given session's common_name
90 */
91static void
92set_common_name(struct tls_session *session, const char *common_name)
93{
94 if (session->common_name)
95 {
96 free(session->common_name);
97 session->common_name = NULL;
98 }
99 if (common_name)
100 {
101 /* FIXME: Last alloc will never be freed */
102 session->common_name = string_alloc(common_name, NULL);
103 }
104 /* update common name in env */
105 setenv_str(session->opt->es, "common_name", common_name);
106}
107
108/*
109 * Retrieve the common name for the given tunnel's active session. If the
110 * common name is NULL or empty, return NULL if null is true, or "UNDEF" if
111 * null is false.
112 */
113const char *
114tls_common_name(const struct tls_multi *multi, const bool null)
115{
116 const char *ret = NULL;
117 if (multi)
118 {
119 ret = multi->session[TM_ACTIVE].common_name;
120 }
121 if (ret && strlen(ret))
122 {
123 return ret;
124 }
125 else if (null)
126 {
127 return NULL;
128 }
129 else
130 {
131 return "UNDEF";
132 }
133}
134
135/*
136 * Lock the common name for the given tunnel.
137 */
138void
140{
141 const char *cn = multi->session[TM_ACTIVE].common_name;
142 if (cn && !multi->locked_cn)
143 {
144 multi->locked_cn = string_alloc(cn, NULL);
145 }
146}
147
148/*
149 * Lock the username for the given tunnel
150 */
151static bool
152tls_lock_username(struct tls_multi *multi, const char *username)
153{
154 if (multi->locked_username)
155 {
156 if (strcmp(username, multi->locked_username) != 0)
157 {
158 msg(D_TLS_ERRORS, "TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled",
159 multi->locked_username,
160 username);
161
162 /* disable the tunnel */
163 tls_deauthenticate(multi);
164 return false;
165 }
166 }
167 else
168 {
169 multi->locked_username = string_alloc(username, NULL);
170 }
171 return true;
172}
173
174const char *
175tls_username(const struct tls_multi *multi, const bool null)
176{
177 const char *ret = NULL;
178 if (multi)
179 {
180 ret = multi->locked_username;
181 }
182 if (ret && strlen(ret))
183 {
184 return ret;
185 }
186 else if (null)
187 {
188 return NULL;
189 }
190 else
191 {
192 return "UNDEF";
193 }
194}
195
196void
197cert_hash_remember(struct tls_session *session, const int error_depth,
198 const struct buffer *cert_hash)
199{
200 if (error_depth >= 0 && error_depth < MAX_CERT_DEPTH)
201 {
202 if (!session->cert_hash_set)
203 {
204 ALLOC_OBJ_CLEAR(session->cert_hash_set, struct cert_hash_set);
205 }
206 if (!session->cert_hash_set->ch[error_depth])
207 {
208 ALLOC_OBJ(session->cert_hash_set->ch[error_depth], struct cert_hash);
209 }
210
211 struct cert_hash *ch = session->cert_hash_set->ch[error_depth];
212 ASSERT(sizeof(ch->sha256_hash) == BLEN(cert_hash));
213 memcpy(ch->sha256_hash, BPTR(cert_hash), sizeof(ch->sha256_hash));
214 }
215}
216
217void
219{
220 if (chs)
221 {
222 int i;
223 for (i = 0; i < MAX_CERT_DEPTH; ++i)
224 {
225 free(chs->ch[i]);
226 }
227 free(chs);
228 }
229}
230
231bool
232cert_hash_compare(const struct cert_hash_set *chs1, const struct cert_hash_set *chs2)
233{
234 if (chs1 && chs2)
235 {
236 int i;
237 for (i = 0; i < MAX_CERT_DEPTH; ++i)
238 {
239 const struct cert_hash *ch1 = chs1->ch[i];
240 const struct cert_hash *ch2 = chs2->ch[i];
241
242 if (!ch1 && !ch2)
243 {
244 continue;
245 }
246 else if (ch1 && ch2 && !memcmp(ch1->sha256_hash, ch2->sha256_hash,
247 sizeof(ch1->sha256_hash)))
248 {
249 continue;
250 }
251 else
252 {
253 return false;
254 }
255 }
256 return true;
257 }
258 else if (!chs1 && !chs2)
259 {
260 return true;
261 }
262 else
263 {
264 return false;
265 }
266}
267
268static struct cert_hash_set *
270{
271 struct cert_hash_set *dest = NULL;
272 if (chs)
273 {
274 int i;
275 ALLOC_OBJ_CLEAR(dest, struct cert_hash_set);
276 for (i = 0; i < MAX_CERT_DEPTH; ++i)
277 {
278 const struct cert_hash *ch = chs->ch[i];
279 if (ch)
280 {
281 ALLOC_OBJ(dest->ch[i], struct cert_hash);
282 memcpy(dest->ch[i]->sha256_hash, ch->sha256_hash,
283 sizeof(dest->ch[i]->sha256_hash));
284 }
285 }
286 }
287 return dest;
288}
289void
291{
292 const struct cert_hash_set *chs = multi->session[TM_ACTIVE].cert_hash_set;
293 if (chs && !multi->locked_cert_hash_set)
294 {
296 }
297}
298
299/*
300 * Returns the string associated with the given certificate type.
301 */
302static const char *
304{
305 switch (type)
306 {
308 return "SERVER";
309
311 return "CLIENT";
312
313 default:
314 return "?";
315 }
316}
317
318/*
319 * Verify the peer's certificate fields.
320 *
321 * @param opt the tls options to verify against
322 * @param peer_cert the peer's certificate
323 * @param subject the peer's extracted subject name
324 * @param subject the peer's extracted common name
325 */
326static result_t
328 const char *subject, const char *common_name)
329{
330 /* verify certificate nsCertType */
332 {
333 if (SUCCESS == x509_verify_ns_cert_type(peer_cert, opt->ns_cert_type))
334 {
335 msg(D_HANDSHAKE, "VERIFY OK: nsCertType=%s",
337 }
338 else
339 {
340 msg(D_HANDSHAKE, "VERIFY nsCertType ERROR: %s, require nsCertType=%s",
341 subject, print_nsCertType(opt->ns_cert_type));
342 return FAILURE; /* Reject connection */
343 }
344 }
345
346 /* verify certificate ku */
347 if (opt->remote_cert_ku[0] != 0)
348 {
349 if (SUCCESS == x509_verify_cert_ku(peer_cert, opt->remote_cert_ku, MAX_PARMS))
350 {
351 msg(D_HANDSHAKE, "VERIFY KU OK");
352 }
353 else
354 {
355 msg(D_HANDSHAKE, "VERIFY KU ERROR");
356 return FAILURE; /* Reject connection */
357 }
358 }
359
360 /* verify certificate eku */
361 if (opt->remote_cert_eku != NULL)
362 {
363 if (SUCCESS == x509_verify_cert_eku(peer_cert, opt->remote_cert_eku))
364 {
365 msg(D_HANDSHAKE, "VERIFY EKU OK");
366 }
367 else
368 {
369 msg(D_HANDSHAKE, "VERIFY EKU ERROR");
370 return FAILURE; /* Reject connection */
371 }
372 }
373
374 /* verify X509 name or username against --verify-x509-[user]name */
376 {
378 && strcmp(opt->verify_x509_name, subject) == 0)
380 && strcmp(opt->verify_x509_name, common_name) == 0)
382 && strncmp(opt->verify_x509_name, common_name,
383 strlen(opt->verify_x509_name)) == 0) )
384 {
385 msg(D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject);
386 }
387 else
388 {
389 msg(D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s",
390 subject, opt->verify_x509_name);
391 return FAILURE; /* Reject connection */
392 }
393 }
394
395 return SUCCESS;
396}
397
398/*
399 * Export the subject, common_name, and raw certificate fields to the
400 * environment for later verification by scripts and plugins.
401 */
402static void
403verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth,
404 const char *subject,
405 const struct x509_track *x509_track)
406{
407 char envname[64];
408 char *serial = NULL;
409 struct gc_arena gc = gc_new();
410
411 /* Save X509 fields in environment */
412 if (x509_track)
413 {
414 x509_setenv_track(x509_track, es, cert_depth, peer_cert);
415 }
416 else
417 {
418 x509_setenv(es, cert_depth, peer_cert);
419 }
420
421 /* export subject name string as environmental variable */
422 snprintf(envname, sizeof(envname), "tls_id_%d", cert_depth);
423 setenv_str(es, envname, subject);
424
425 /* export X509 cert fingerprints */
426 {
429
430 snprintf(envname, sizeof(envname), "tls_digest_%d", cert_depth);
432 format_hex_ex(BPTR(&sha1), BLEN(&sha1), 0, 1, ":", &gc));
433
434 snprintf(envname, sizeof(envname), "tls_digest_sha256_%d",
435 cert_depth);
437 format_hex_ex(BPTR(&sha256), BLEN(&sha256), 0, 1, ":", &gc));
438 }
439
440 /* export serial number as environmental variable */
442 snprintf(envname, sizeof(envname), "tls_serial_%d", cert_depth);
444
445 /* export serial number in hex as environmental variable */
447 snprintf(envname, sizeof(envname), "tls_serial_hex_%d", cert_depth);
449
450 gc_free(&gc);
451}
452
457static bool
459 const char *pem_export_fname)
460{
461 /* export the path to the current certificate in pem file format */
462 setenv_str(es, "peer_cert", pem_export_fname);
463
465}
466
467static void
469{
470 env_set_del(es, "peer_cert");
472 {
474 }
475}
476
477/*
478 * call --tls-verify plug-in(s)
479 */
480static result_t
481verify_cert_call_plugin(const struct plugin_list *plugins, struct env_set *es,
482 int cert_depth, openvpn_x509_cert_t *cert, char *subject)
483{
485 {
486 int ret;
487 struct argv argv = argv_new();
488
489 argv_printf(&argv, "%d %s", cert_depth, subject);
490
491 ret = plugin_call_ssl(plugins, OPENVPN_PLUGIN_TLS_VERIFY, &argv, NULL, es, cert_depth, cert);
492
493 argv_free(&argv);
494
495 if (ret == OPENVPN_PLUGIN_FUNC_SUCCESS)
496 {
497 msg(D_HANDSHAKE, "VERIFY PLUGIN OK: depth=%d, %s",
498 cert_depth, subject);
499 }
500 else
501 {
502 msg(D_HANDSHAKE, "VERIFY PLUGIN ERROR: depth=%d, %s",
503 cert_depth, subject);
504 return FAILURE; /* Reject connection */
505 }
506 }
507 return SUCCESS;
508}
509
510/*
511 * run --tls-verify script
512 */
513static result_t
514verify_cert_call_command(const char *verify_command, struct env_set *es,
515 int cert_depth, char *subject)
516{
517 int ret;
518 struct gc_arena gc = gc_new();
519 struct argv argv = argv_new();
520
521 setenv_str(es, "script_type", "tls-verify");
522
523 argv_parse_cmd(&argv, verify_command);
524 argv_printf_cat(&argv, "%d %s", cert_depth, subject);
525
526 argv_msg_prefix(D_TLS_DEBUG, &argv, "TLS: executing verify command");
527 ret = openvpn_run_script(&argv, es, 0, "--tls-verify script");
528
529 gc_free(&gc);
530 argv_free(&argv);
531
532 if (ret)
533 {
534 msg(D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s",
535 cert_depth, subject);
536 return SUCCESS;
537 }
538
539 msg(D_HANDSHAKE, "VERIFY SCRIPT ERROR: depth=%d, %s",
540 cert_depth, subject);
541 return FAILURE; /* Reject connection */
542}
543
544/*
545 * check peer cert against CRL directory
546 */
547static result_t
548verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert,
549 const char *subject, int cert_depth)
550{
551 result_t ret = FAILURE;
552 char fn[256];
553 int fd = -1;
554 struct gc_arena gc = gc_new();
555
556 char *serial = backend_x509_get_serial(cert, &gc);
557 if (!serial)
558 {
559 msg(D_HANDSHAKE, "VERIFY CRL: depth=%d, %s, serial number is not available",
560 cert_depth, subject);
561 goto cleanup;
562 }
563
564 if (!snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, PATH_SEPARATOR, serial))
565 {
566 msg(D_HANDSHAKE, "VERIFY CRL: filename overflow");
567 goto cleanup;
568 }
569 fd = platform_open(fn, O_RDONLY, 0);
570 if (fd >= 0)
571 {
572 msg(D_HANDSHAKE, "VERIFY CRL: depth=%d, %s, serial=%s is revoked",
573 cert_depth, subject, serial);
574 goto cleanup;
575 }
576
577 ret = SUCCESS;
578
579cleanup:
580
581 if (fd != -1)
582 {
583 close(fd);
584 }
585 gc_free(&gc);
586 return ret;
587}
588
590verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
591{
592 /* need to define these variables here so goto cleanup will always have
593 * them defined */
594 result_t ret = FAILURE;
595 struct gc_arena gc = gc_new();
596 const char *pem_export_fname = NULL;
597
598 const struct tls_options *opt = session->opt;
599 ASSERT(opt);
600
601 session->verified = false;
602
603 /* get the X509 name */
604 char *subject = x509_get_subject(cert, &gc);
605 if (!subject)
606 {
607 msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
608 "subject string from certificate", cert_depth);
609 goto cleanup;
610 }
611
612 /* enforce character class restrictions in X509 name */
613 string_mod_remap_name(subject);
614 string_replace_leading(subject, '-', '_');
615
616 /* extract the username (default is CN) */
617 struct buffer buf = alloc_buf_gc(256, &gc);
618 for (int i = 0; opt->x509_username_field[i] != NULL; i++)
619 {
620 char username[TLS_USERNAME_LEN+1] = {0}; /* null-terminated */
621
622 if (SUCCESS != backend_x509_get_username(username, sizeof(username),
623 opt->x509_username_field[i], cert))
624 {
625 if (!cert_depth)
626 {
627 msg(D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 "
628 "subject string ('%s') -- note that the field length is "
629 "limited to %d characters",
631 subject,
633 goto cleanup;
634 }
635 break;
636 }
637 if (!buf_printf(&buf, i ? "_%s" : "%s", username))
638 {
639 if (!cert_depth)
640 {
641 msg(D_TLS_ERRORS, "VERIFY ERROR: could not append %s from X509 "
642 "certificate -- note that the username length is "
643 "limited to %d characters",
645 buf.capacity - 1);
646 goto cleanup;
647 }
648 break;
649 }
650 }
651
652 char *common_name = BSTR(&buf);
653 if (!common_name)
654 {
655 msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
656 "username string from certificate", cert_depth);
657 goto cleanup;
658 }
659
660 /* enforce character class restrictions in common name */
661 string_mod_remap_name(common_name);
662
663 /* warn if cert chain is too deep */
665 {
666 msg(D_TLS_ERRORS, "TLS Error: Convoluted certificate chain detected with depth [%d] greater than %d", cert_depth, MAX_CERT_DEPTH);
667 goto cleanup; /* Reject connection */
668 }
669
670 if (cert_depth == opt->verify_hash_depth && opt->verify_hash)
671 {
672 struct buffer cert_fp = {0};
673
674 switch (opt->verify_hash_algo)
675 {
676 case MD_SHA1:
678 break;
679
680 case MD_SHA256:
682 break;
683
684 default:
685 /* This should normally not happen at all; the algorithm used
686 * is parsed by add_option() [options.c] and set to a predefined
687 * value in an enumerated type. So if this unlikely scenario
688 * happens, consider this a failure
689 */
690 msg(M_WARN, "Unexpected invalid algorithm used with "
691 "--verify-hash (%i)", opt->verify_hash_algo);
692 ret = FAILURE;
693 goto cleanup;
694 }
695
696 struct verify_hash_list *current_hash = opt->verify_hash;
697
698 while (current_hash)
699 {
700 if (memcmp_constant_time(BPTR(&cert_fp), current_hash->hash,
701 BLEN(&cert_fp)) == 0)
702 {
703 break;
704 }
705 current_hash = current_hash->next;
706 }
707
708 if (!current_hash)
709 {
710 const char *hex_fp = format_hex_ex(BPTR(&cert_fp), BLEN(&cert_fp),
711 0, 1, ":", &gc);
712 msg(D_TLS_ERRORS, "TLS Error: --tls-verify/--peer-fingerprint "
713 "certificate hash verification failed. (got certificate "
714 "fingerprint: %s)", hex_fp);
715 goto cleanup;
716 }
717 }
718
719 /* save common name in session object */
720 if (cert_depth == 0)
721 {
722 set_common_name(session, common_name);
723 }
724
725 session->verify_maxlevel = max_int(session->verify_maxlevel, cert_depth);
726
727 if (opt->export_peer_cert_dir)
728 {
729 pem_export_fname = platform_create_temp_file(opt->export_peer_cert_dir,
730 "pef", &gc);
731
732 if (!pem_export_fname
733 || !verify_cert_cert_export_env(opt->es, cert, pem_export_fname))
734 {
735 msg(D_TLS_ERRORS, "TLS Error: Failed to export certificate for "
736 "--tls-export-cert in %s", opt->export_peer_cert_dir);
737 goto cleanup;
738 }
739 }
740 /* export certificate values to the environment */
741 verify_cert_set_env(opt->es, cert, cert_depth, subject, opt->x509_track);
742
743 /* export current untrusted IP */
745
746 /* If this is the peer's own certificate, verify it */
747 if (cert_depth == 0 && SUCCESS != verify_peer_cert(opt, cert, subject, common_name))
748 {
749 goto cleanup;
750 }
751
752 /* call --tls-verify plug-in(s), if registered */
753 if (SUCCESS != verify_cert_call_plugin(opt->plugins, opt->es, cert_depth, cert, subject))
754 {
755 goto cleanup;
756 }
757
758 /* run --tls-verify script */
760 opt->es, cert_depth, subject))
761 {
762 goto cleanup;
763 }
764
765 /* check peer cert against CRL */
766 if (opt->crl_file)
767 {
769 {
770 if (SUCCESS != verify_check_crl_dir(opt->crl_file, cert, subject, cert_depth))
771 {
772 goto cleanup;
773 }
774 }
775 else
776 {
777 if (tls_verify_crl_missing(opt))
778 {
779 msg(D_TLS_ERRORS, "VERIFY ERROR: CRL not loaded");
780 goto cleanup;
781 }
782 }
783 }
784
785 msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject);
786 session->verified = true;
787 ret = SUCCESS;
788
789cleanup:
790 verify_cert_cert_delete_env(opt->es, pem_export_fname);
791 if (ret != SUCCESS)
792 {
793 tls_clear_error(); /* always? */
794 session->verified = false; /* double sure? */
795 }
796
797 gc_free(&gc);
798
799 return ret;
800}
801
802/* ***************************************************************************
803* Functions for the management of deferred authentication when using
804* user/password authentication.
805*************************************************************************** */
806
807void
808auth_set_client_reason(struct tls_multi *multi, const char *client_reason)
809{
810 free(multi->client_reason);
811 multi->client_reason = NULL;
812
813 if (client_reason && strlen(client_reason))
814 {
815 multi->client_reason = string_alloc(client_reason, NULL);
816 }
817}
818
819#ifdef ENABLE_MANAGEMENT
820
821static inline enum auth_deferred_result
823{
825 {
826 return ks->mda_status;
827 }
828 else
829 {
830 return ACF_DISABLED;
831 }
832}
833#endif /* ifdef ENABLE_MANAGEMENT */
834
839static void
841{
842 if (ads && ads->auth_pending_file)
843 {
845 free(ads->auth_pending_file);
846 ads->auth_pending_file = NULL;
847 }
848}
849
853static bool
854check_auth_pending_method(const char *peer_info, const char *method)
855{
856 struct gc_arena gc = gc_new();
857
858 char *iv_sso = extract_var_peer_info(peer_info, "IV_SSO=", &gc);
859 if (!iv_sso)
860 {
861 gc_free(&gc);
862 return false;
863 }
864
865 const char *client_method = strtok(iv_sso, ",");
866 bool supported = false;
867
868 while (client_method)
869 {
870 if (0 == strcmp(client_method, method))
871 {
872 supported = true;
873 break;
874 }
875 client_method = strtok(NULL, ",");
876 }
877
878 gc_free(&gc);
879 return supported;
880}
881
890static bool
892 struct tls_multi *multi,
893 struct tls_session *session)
894{
895 bool ret = true;
896 if (ads->auth_pending_file)
897 {
899 1024);
900 if (lines && lines->head)
901 {
902 /* Must have at least three lines. further lines are ignored for
903 * forward compatibility */
904 if (!lines->head || !lines->head->next || !lines->head->next->next)
905 {
906 msg(M_WARN, "auth pending control file is not at least "
907 "three lines long.");
908 buffer_list_free(lines);
909 return false;
910 }
911 struct buffer *timeout_buf = &lines->head->buf;
912 struct buffer *iv_buf = &lines->head->next->buf;
913 struct buffer *extra_buf = &lines->head->next->next->buf;
914
915 /* Remove newline chars at the end of the lines */
919
920 long timeout = strtol(BSTR(timeout_buf), NULL, 10);
921 if (timeout == 0)
922 {
923 msg(M_WARN, "could not parse auth pending file timeout");
925 return false;
926 }
927
928 const char *pending_method = BSTR(iv_buf);
930 {
931 char buf[128];
932 snprintf(buf, sizeof(buf),
933 "Authentication failed, required pending auth "
934 "method '%s' not supported", pending_method);
935 auth_set_client_reason(multi, buf);
936 msg(M_INFO, "Client does not supported auth pending method "
937 "'%s'", pending_method);
938 ret = false;
939 }
940 else
941 {
943 }
944 }
945
947 }
949 return ret;
950}
951
952
957void
959{
960 if (ads->auth_control_file)
961 {
962 platform_unlink(ads->auth_control_file);
963 free(ads->auth_control_file);
964 ads->auth_control_file = NULL;
965 }
966 if (ads->auth_failed_reason_file)
967 {
968 platform_unlink(ads->auth_failed_reason_file);
969 free(ads->auth_failed_reason_file);
970 ads->auth_failed_reason_file = NULL;
971 }
973}
974
981static bool
983 const struct tls_options *opt)
984{
985 struct gc_arena gc = gc_new();
986
988 const char *acf = platform_create_temp_file(opt->tmp_dir, "acf", &gc);
989 const char *apf = platform_create_temp_file(opt->tmp_dir, "apf", &gc);
990 const char *afr = platform_create_temp_file(opt->tmp_dir, "afr", &gc);
991
992 if (acf && apf)
993 {
994 ads->auth_control_file = string_alloc(acf, NULL);
995 ads->auth_pending_file = string_alloc(apf, NULL);
996 ads->auth_failed_reason_file = string_alloc(afr, NULL);
997
998 setenv_str(opt->es, "auth_control_file", ads->auth_control_file);
999 setenv_str(opt->es, "auth_pending_file", ads->auth_pending_file);
1000 setenv_str(opt->es, "auth_failed_reason_file", ads->auth_failed_reason_file);
1001 }
1002
1003 gc_free(&gc);
1004 return (acf && apf);
1005}
1006
1011static char *
1013 struct gc_arena *gc)
1014{
1015 char *ret = NULL;
1016 if (ads->auth_failed_reason_file)
1017 {
1018 struct buffer reason = buffer_read_from_file(ads->auth_failed_reason_file, gc);
1019
1020 if (BLEN(&reason))
1021 {
1022 ret = BSTR(&reason);
1023 }
1024
1025 }
1026 return ret;
1027}
1028
1029
1040static enum auth_deferred_result
1042{
1043 if (ads->auth_control_file)
1044 {
1045 unsigned int ret = ads->auth_control_status;
1046 if (ret == ACF_PENDING && !cached)
1047 {
1048 FILE *fp = fopen(ads->auth_control_file, "r");
1049 if (fp)
1050 {
1051 const int c = fgetc(fp);
1052 if (c == '1')
1053 {
1054 ret = ACF_SUCCEEDED;
1055 }
1056 else if (c == '0')
1057 {
1058 ret = ACF_FAILED;
1059 }
1060 fclose(fp);
1061 ads->auth_control_status = ret;
1062 }
1063 }
1064 return ret;
1065 }
1066 return ACF_DISABLED;
1067}
1068
1076static void
1078{
1079 if (ks->authenticated == KS_AUTH_FALSE)
1080 {
1081 return;
1082 }
1083 else
1084 {
1090#ifdef ENABLE_MANAGEMENT
1092#endif
1093 ASSERT(auth_plugin < 4 && auth_script < 4 && auth_man < 4);
1094
1096 || auth_man == ACF_FAILED)
1097 {
1099 return;
1100 }
1102 || auth_man == ACF_PENDING)
1103 {
1104 if (now >= ks->auth_deferred_expire)
1105 {
1106 /* Window to authenticate the key has expired, mark
1107 * the key as unauthenticated */
1109 }
1110 }
1111 else
1112 {
1113 /* all auth states (auth_plugin, auth_script, auth_man)
1114 * are either ACF_DISABLED or ACF_SUCCEDED now, which
1115 * translates to "not checked" or "auth succeeded"
1116 */
1118 }
1119 }
1120}
1121
1122
1129static time_t cache_intervals[] = {0, 0, 0, 0, 0, 1, 1, 2, 2, 4, 8};
1130
1135static bool
1137{
1138 unsigned int idx = min_uint(multi->tas_cache_num_updates, SIZE(cache_intervals) - 1);
1140 return multi->tas_cache_last_update + latency >= now;
1141}
1142
1143enum tls_auth_status
1145{
1146 bool deferred = false;
1147
1148 /* at least one valid key has successfully completed authentication */
1149 bool success = false;
1150
1151 /* at least one key is enabled for decryption */
1152 int active = 0;
1153
1154 /* at least one key already failed authentication */
1155 bool failed_auth = false;
1156
1158
1159 for (int i = 0; i < KEY_SCAN_SIZE; ++i)
1160 {
1161 struct key_state *ks = get_key_scan(multi, i);
1162 if (TLS_AUTHENTICATED(multi, ks))
1163 {
1164 active++;
1165 update_key_auth_status(cached, ks);
1166
1167 if (ks->authenticated == KS_AUTH_FALSE)
1168 {
1169 failed_auth = true;
1170 }
1171 else if (ks->authenticated == KS_AUTH_DEFERRED)
1172 {
1173 deferred = true;
1174 }
1175 else if (ks->authenticated == KS_AUTH_TRUE)
1176 {
1177 success = true;
1178 }
1179 }
1180 }
1181
1182 /* we did not rely on a cached result, remember the cache update time */
1183 if (!cached)
1184 {
1185 multi->tas_cache_last_update = now;
1186 multi->tas_cache_num_updates++;
1187 }
1188
1189#if 0
1190 dmsg(D_TLS_ERRORS, "TAS: a=%d s=%d d=%d f=%d", active, success, deferred, failed_auth);
1191#endif
1192 if (failed_auth)
1193 {
1194 struct gc_arena gc = gc_new();
1195 const struct key_state *ks = get_primary_key(multi);
1196 const char *plugin_message = key_state_check_auth_failed_message_file(&ks->plugin_auth, &gc);
1197 const char *script_message = key_state_check_auth_failed_message_file(&ks->script_auth, &gc);
1198
1199 if (plugin_message)
1200 {
1201 auth_set_client_reason(multi, plugin_message);
1202 }
1203 if (script_message)
1204 {
1205 auth_set_client_reason(multi, script_message);
1206 }
1207
1208 /* We have at least one session that failed authentication. There
1209 * might be still another session with valid keys.
1210 * Although our protocol allows keeping the VPN session alive
1211 * with the other session (and we actually did that in earlier
1212 * version, this behaviour is really strange from a user (admin)
1213 * experience */
1214 gc_free(&gc);
1216 }
1217 else if (success)
1218 {
1220 }
1221 else if (active == 0 || deferred)
1222 {
1223 /* We have a deferred authentication and no currently active key
1224 * (first auth, no renegotiation) */
1226 }
1227 else
1228 {
1229 /* at least one key is active but none is fully authenticated (!success)
1230 * and all active are either failed authed or expired deferred auth */
1232 }
1233}
1234
1235#ifdef ENABLE_MANAGEMENT
1236/*
1237 * For deferred auth, this is where the management interface calls (on server)
1238 * to indicate auth failure/success.
1239 */
1240bool
1241tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason)
1242{
1243 bool ret = false;
1244 if (multi)
1245 {
1246 int i;
1247 auth_set_client_reason(multi, client_reason);
1248 for (i = 0; i < KEY_SCAN_SIZE; ++i)
1249 {
1250 struct key_state *ks = get_key_scan(multi, i);
1251 if (ks->mda_key_id == mda_key_id)
1252 {
1253 ks->mda_status = auth ? ACF_SUCCEEDED : ACF_FAILED;
1254 ret = true;
1255 }
1256 }
1257 }
1258 return ret;
1259}
1260#endif /* ifdef ENABLE_MANAGEMENT */
1261
1262
1263/* ****************************************************************************
1264 * Functions to verify username and password
1265 *
1266 * Authenticate a client using username/password.
1267 * Runs on server.
1268 *
1269 * If you want to add new authentication methods,
1270 * this is the place to start.
1271 *************************************************************************** */
1272
1276static void
1279{
1280 struct gc_arena gc = gc_new();
1282 if (msg)
1283 {
1285 }
1286 gc_free(&gc);
1287}
1288/*
1289 * Verify the user name and password using a script
1290 */
1291static int
1293 const struct user_pass *up)
1294{
1295 struct gc_arena gc = gc_new();
1296 struct argv argv = argv_new();
1297 const char *tmp_file = "";
1298 int retval = OPENVPN_PLUGIN_FUNC_ERROR;
1299 struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1300
1301 /* Set environmental variables prior to calling script */
1302 setenv_str(session->opt->es, "script_type", "user-pass-verify");
1303
1304 /* format command line */
1305 argv_parse_cmd(&argv, session->opt->auth_user_pass_verify_script);
1306
1307 if (session->opt->auth_user_pass_verify_script_via_file)
1308 {
1309 struct status_output *so;
1310
1311 tmp_file = platform_create_temp_file(session->opt->tmp_dir, "up",
1312 &gc);
1313 if (tmp_file)
1314 {
1315 so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE);
1316 status_printf(so, "%s", up->username);
1317 status_printf(so, "%s", up->password);
1318 if (!status_close(so))
1319 {
1320 msg(D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s",
1321 tmp_file);
1322 goto done;
1323 }
1324 /* pass temp file name to script */
1325 argv_printf_cat(&argv, "%s", tmp_file);
1326 }
1327 }
1328 else
1329 {
1330 setenv_str(session->opt->es, "username", up->username);
1331 setenv_str(session->opt->es, "password", up->password);
1332 }
1333
1334 /* pre-create files for deferred auth control */
1336 {
1337 msg(D_TLS_ERRORS, "TLS Auth Error (%s): "
1338 "could not create deferred auth control file", __func__);
1339 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1340 goto error;
1341 }
1342
1343 /* call command */
1344 int script_ret = openvpn_run_script(&argv, session->opt->es, S_EXITCODE,
1345 "--auth-user-pass-verify");
1346 switch (script_ret)
1347 {
1348 case 0:
1349 retval = OPENVPN_PLUGIN_FUNC_SUCCESS;
1350 break;
1351
1352 case 2:
1353 retval = OPENVPN_PLUGIN_FUNC_DEFERRED;
1354 break;
1355
1356 default:
1358 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1359 break;
1360 }
1361 if (retval == OPENVPN_PLUGIN_FUNC_DEFERRED)
1362 {
1363 /* Check if we the plugin has written the pending auth control
1364 * file and send the pending auth to the client */
1366 multi, session))
1367 {
1368 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1370 }
1371
1372 }
1373 else
1374 {
1375 /* purge auth control filename (and file itself) for non-deferred returns */
1377 }
1378 if (!session->opt->auth_user_pass_verify_script_via_file)
1379 {
1380 setenv_del(session->opt->es, "password");
1381 }
1382
1383done:
1384 if (tmp_file && strlen(tmp_file) > 0)
1385 {
1386 platform_unlink(tmp_file);
1387 }
1388
1389error:
1390 argv_free(&argv);
1391 gc_free(&gc);
1392 return retval;
1393}
1394
1395#ifdef ENABLE_PLUGIN
1396void
1397verify_crresponse_plugin(struct tls_multi *multi, const char *cr_response)
1398{
1399 struct tls_session *session = &multi->session[TM_ACTIVE];
1400 setenv_str(session->opt->es, "crresponse", cr_response);
1401
1402 plugin_call(session->opt->plugins, OPENVPN_PLUGIN_CLIENT_CRRESPONSE, NULL,
1403 NULL, session->opt->es);
1404
1405 setenv_del(session->opt->es, "crresponse");
1406}
1407#endif
1408
1409void
1410verify_crresponse_script(struct tls_multi *multi, const char *cr_response)
1411{
1412
1413 struct tls_session *session = &multi->session[TM_ACTIVE];
1414
1415 if (!session->opt->client_crresponse_script)
1416 {
1417 return;
1418 }
1419 struct argv argv = argv_new();
1420 struct gc_arena gc = gc_new();
1421
1422 setenv_str(session->opt->es, "script_type", "client-crresponse");
1423
1424 /* Since cr response might be sensitive, like a stupid way to query
1425 * a password via 2FA, we pass it via file instead environment */
1426 const char *tmp_file = platform_create_temp_file(session->opt->tmp_dir, "cr", &gc);
1427 static const char *openerrmsg = "TLS CR Response Error: could not write "
1428 "crtext challenge response to file: %s";
1429
1430 if (tmp_file)
1431 {
1432 struct status_output *so = status_open(tmp_file, 0, -1, NULL,
1434 status_printf(so, "%s", cr_response);
1435 if (!status_close(so))
1436 {
1437 msg(D_TLS_ERRORS, openerrmsg, tmp_file);
1438 tls_deauthenticate(multi);
1439 goto done;
1440 }
1441 }
1442 else
1443 {
1444 msg(D_TLS_ERRORS, openerrmsg, "creating file failed");
1445 tls_deauthenticate(multi);
1446 goto done;
1447 }
1448
1449 argv_parse_cmd(&argv, session->opt->client_crresponse_script);
1450 argv_printf_cat(&argv, "%s", tmp_file);
1451
1452
1453 if (!openvpn_run_script(&argv, session->opt->es, 0, "--client-crresponse"))
1454 {
1455 tls_deauthenticate(multi);
1456 }
1457done:
1458 argv_free(&argv);
1459 gc_free(&gc);
1460}
1461
1462/*
1463 * Verify the username and password using a plugin
1464 */
1465static int
1467 const struct user_pass *up)
1468{
1469 int retval = OPENVPN_PLUGIN_FUNC_ERROR;
1470 struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1471
1472 /* set password in private env space */
1473 setenv_str(session->opt->es, "password", up->password);
1474
1475 /* generate filename for deferred auth control file */
1477 {
1478 msg(D_TLS_ERRORS, "TLS Auth Error (%s): "
1479 "could not create deferred auth control file", __func__);
1480 return retval;
1481 }
1482
1483 /* call command */
1484 retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es);
1485
1486 if (retval == OPENVPN_PLUGIN_FUNC_DEFERRED)
1487 {
1488 /* Check if the plugin has written the pending auth control
1489 * file and send the pending auth to the client */
1491 {
1492 retval = OPENVPN_PLUGIN_FUNC_ERROR;
1493 }
1494 }
1495
1496 if (retval == OPENVPN_PLUGIN_FUNC_ERROR)
1497 {
1499 }
1500
1501 if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED)
1502 {
1503 /* purge auth control filename (and file itself) for non-deferred returns */
1505 }
1506
1507 setenv_del(session->opt->es, "password");
1508
1509 return retval;
1510}
1511
1512
1513#ifdef ENABLE_MANAGEMENT
1514/*
1515 * management deferred internal ssl_verify.c status codes
1516 */
1517#define KMDA_ERROR 0
1518#define KMDA_SUCCESS 1
1519#define KMDA_UNDEF 2
1520#define KMDA_DEF 3
1521
1522static int
1524 const struct user_pass *up)
1525{
1526 int retval = KMDA_ERROR;
1527 struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1528
1529 /* set username/password in private env space */
1530 setenv_str(session->opt->es, "password", up->password);
1531
1532 if (management)
1533 {
1535 }
1536
1537 setenv_del(session->opt->es, "password");
1538
1539 retval = KMDA_SUCCESS;
1540
1541 return retval;
1542}
1543#endif /* ifdef ENABLE_MANAGEMENT */
1544
1545static bool
1547 struct tls_session *session)
1548{
1549 /* Is username defined? */
1550 if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username))
1551 {
1552 setenv_str(session->opt->es, "username", up->username);
1553
1554 /* setenv incoming cert common name for script */
1555 setenv_str(session->opt->es, "common_name", session->common_name);
1556
1557 /* setenv client real IP address */
1559
1560 /*
1561 * if we are using auth-gen-token, send also the session id of auth gen token to
1562 * allow the management to figure out if it is a new session or a continued one
1563 */
1564 add_session_token_env(session, multi, up);
1565 return true;
1566 }
1567 else
1568 {
1569 msg(D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username");
1570 return false;
1571 }
1572}
1573
1580void
1581verify_user_pass(struct user_pass *up, struct tls_multi *multi,
1582 struct tls_session *session)
1583{
1584 struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1585
1586 ASSERT(up && !up->protected);
1587
1588#ifdef ENABLE_MANAGEMENT
1589 int man_def_auth = KMDA_UNDEF;
1590
1592 {
1593 man_def_auth = KMDA_DEF;
1594 }
1595#endif
1596
1597 /* enforce character class restrictions in username/password */
1599 string_mod(up->password, CC_PRINT, CC_CRLF, '_');
1600
1601 /*
1602 * If auth token succeeds we skip the auth
1603 * methods unless otherwise specified
1604 */
1605 bool skip_auth = false;
1606
1607 /*
1608 * If server is configured with --auth-gen-token and the client sends
1609 * something that looks like an authentication token, this
1610 * round will be done internally using the token instead of
1611 * calling any external authentication modules.
1612 */
1613 if (session->opt->auth_token_generate && is_auth_token(up->password))
1614 {
1616
1617 /* If this is the first time we see an auth-token in this multi session,
1618 * save it as initial auth token. This ensures using the
1619 * same session ID and initial timestamp in new tokens */
1620 if (!multi->auth_token_initial)
1621 {
1622 multi->auth_token_initial = strdup(up->password);
1623 }
1624
1625 if (session->opt->auth_token_call_auth)
1626 {
1627 /*
1628 * we do not care about the result here because it is
1629 * the responsibility of the external authentication to
1630 * decide what to do with the result
1631 */
1632 }
1634 {
1635 /*
1636 * We do not want the EXPIRED or EMPTY USER flags here so check
1637 * for equality with AUTH_TOKEN_HMAC_OK
1638 */
1639 msg(M_WARN, "TLS: Username/auth-token authentication "
1640 "succeeded for username '%s'",
1641 up->username);
1642 skip_auth = true;
1643 }
1644 else
1645 {
1646 wipe_auth_token(multi);
1648 msg(M_WARN, "TLS: Username/auth-token authentication "
1649 "failed for username '%s'", up->username);
1650 return;
1651 }
1652 }
1653
1654 int plugin_status = OPENVPN_PLUGIN_FUNC_SUCCESS;
1655 int script_status = OPENVPN_PLUGIN_FUNC_SUCCESS;
1656 /* Set the environment variables used by all auth variants */
1657 if (!set_verify_user_pass_env(up, multi, session))
1658 {
1659 skip_auth = true;
1660 plugin_status = OPENVPN_PLUGIN_FUNC_ERROR;
1661 }
1662
1663 /* call plugin(s) and/or script */
1664 if (!skip_auth)
1665 {
1666#ifdef ENABLE_MANAGEMENT
1667 if (man_def_auth == KMDA_DEF)
1668 {
1669 man_def_auth = verify_user_pass_management(session, up);
1670 }
1671#endif
1672 if (plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY))
1673 {
1674 plugin_status = verify_user_pass_plugin(session, multi, up);
1675 }
1676
1677 if (session->opt->auth_user_pass_verify_script)
1678 {
1679 script_status = verify_user_pass_script(session, multi, up);
1680 }
1681 }
1682
1683 /* check sizing of username if it will become our common name */
1684 if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
1685 && strlen(up->username)>TLS_USERNAME_LEN)
1686 {
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;
1692 }
1693 /* auth succeeded? */
1694 bool plugin_ok = plugin_status == OPENVPN_PLUGIN_FUNC_SUCCESS
1695 || plugin_status == OPENVPN_PLUGIN_FUNC_DEFERRED;
1696
1697 bool script_ok = script_status == OPENVPN_PLUGIN_FUNC_SUCCESS
1698 || script_status == OPENVPN_PLUGIN_FUNC_DEFERRED;
1699
1700 if (script_ok && plugin_ok && tls_lock_username(multi, up->username)
1701#ifdef ENABLE_MANAGEMENT
1702 && man_def_auth != KMDA_ERROR
1703#endif
1704 )
1705 {
1707 if (plugin_status == OPENVPN_PLUGIN_FUNC_DEFERRED
1708 || script_status == OPENVPN_PLUGIN_FUNC_DEFERRED)
1709 {
1711 }
1712#ifdef ENABLE_MANAGEMENT
1713 if (man_def_auth != KMDA_UNDEF)
1714 {
1715 if (skip_auth)
1716 {
1718 }
1719 else
1720 {
1722 }
1723 }
1724#endif
1725 if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
1726 {
1728 }
1729
1730 if ((session->opt->auth_token_generate))
1731 {
1732 /*
1733 * If we accepted a (not expired) token, i.e.
1734 * initial auth via token on new connection, we need
1735 * to store the auth-token in multi->auth_token, so
1736 * the initial timestamp and session id can be extracted from it
1737 */
1738 if (!multi->auth_token
1741 {
1742 multi->auth_token = strdup(up->password);
1743 }
1744
1745 /*
1746 * Server is configured with --auth-gen-token. Generate or renew
1747 * the token.
1748 */
1749 generate_auth_token(up, multi);
1750 }
1751
1752 msg(D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s",
1753 (ks->authenticated == KS_AUTH_DEFERRED) ? "deferred" : "succeeded",
1754 up->username,
1755 (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
1756 }
1757 else
1758 {
1760 msg(D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
1761 }
1762}
1763
1764void
1766{
1767 struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1768
1769 /* While it shouldn't really happen, don't allow the common name to be NULL */
1770 if (!session->common_name)
1771 {
1773 }
1774
1775 /* Don't allow the CN to change once it's been locked */
1776 if (ks->authenticated > KS_AUTH_FALSE && multi->locked_cn)
1777 {
1778 const char *cn = session->common_name;
1779 if (cn && strcmp(cn, multi->locked_cn))
1780 {
1781 msg(D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled",
1782 multi->locked_cn,
1783 cn);
1784
1785 /* change the common name back to its original value and disable the tunnel */
1787 tls_deauthenticate(multi);
1788 }
1789 }
1790
1791 /* Don't allow the cert hashes to change once they have been locked */
1793 {
1794 const struct cert_hash_set *chs = session->cert_hash_set;
1795 if (chs && !cert_hash_compare(chs, multi->locked_cert_hash_set))
1796 {
1797 msg(D_TLS_ERRORS, "TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth",
1798 session->common_name);
1799
1800 /* disable the tunnel */
1801 tls_deauthenticate(multi);
1802 }
1803 }
1804
1805 /* verify --client-config-dir based authentication */
1806 if (ks->authenticated > KS_AUTH_FALSE && session->opt->client_config_dir_exclusive)
1807 {
1808 struct gc_arena gc = gc_new();
1809
1810 const char *cn = session->common_name;
1811 const char *path = platform_gen_path(session->opt->client_config_dir_exclusive,
1812 cn, &gc);
1813 if (!cn || !strcmp(cn, CCD_DEFAULT) || !platform_test_file(path))
1814 {
1816 wipe_auth_token(multi);
1817 msg(D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
1818 session->common_name,
1819 path ? path : "UNDEF");
1820 }
1821
1822 gc_free(&gc);
1823 }
1824}
1825
1826void
1828{
1829 struct env_item *item = es->list;
1830 while (item)
1831 {
1832 struct env_item *next = item->next;
1833 if (item->string
1834 && 0 == strncmp("X509_", item->string, strlen("X509_")))
1835 {
1836 env_set_del(es, item->string);
1837 }
1838 item = next;
1839 }
1840}
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.
Definition argv.c:260
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...
Definition argv.c:483
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:102
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:440
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition argv.c:464
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:88
void generate_auth_token(const struct user_pass *up, struct tls_multi *multi)
Generate an auth token based on username and timestamp.
Definition auth_token.c:164
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...
Definition auth_token.c:294
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.
Definition auth_token.c:38
void wipe_auth_token(struct tls_multi *multi)
Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.
Definition auth_token.c:401
static bool is_auth_token(const char *password)
Return if the password string has the format of a password.
Definition auth_token.h:127
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
void string_replace_leading(char *str, const char match, const char replace)
Definition buffer.c:1109
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Definition buffer.c:1335
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:483
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition buffer.c:1167
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
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...
Definition buffer.c:1041
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
Definition buffer.c:1358
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
void buf_chomp(struct buffer *buf)
Definition buffer.c:554
#define ALLOC_OBJ(dptr, type)
Definition buffer.h:1055
#define BSTR(buf)
Definition buffer.h:129
#define BPTR(buf)
Definition buffer.h:124
#define CC_CRLF
carriage return or newline
Definition buffer.h:920
#define BLEN(buf)
Definition buffer.h:127
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:891
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1060
static struct gc_arena gc_new(void)
Definition buffer.h:1025
#define CCD_DEFAULT
Definition common.h:62
int memcmp_constant_time(const void *a, const void *b, size_t size)
As memcmp(), but constant-time.
@ MD_SHA256
@ MD_SHA1
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:283
bool env_set_del(struct env_set *es, const char *str)
Definition env_set.c:183
void setenv_del(struct env_set *es, const char *name)
Definition env_set.c:328
#define D_HANDSHAKE
Definition errlevel.h:72
#define D_TLS_ERRORS
Definition errlevel.h:59
#define M_INFO
Definition errlevel.h:55
#define D_TLS_DEBUG
Definition errlevel.h:165
#define KS_SIZE
Size of the tls_session.key array.
Definition ssl_common.h:459
#define KS_PRIMARY
Primary key state index.
Definition ssl_common.h:456
#define TM_SIZE
Size of the tls_multi.session array.
Definition ssl_common.h:539
#define TM_ACTIVE
Active tls_session.
Definition ssl_common.h:535
#define TLS_AUTHENTICATED(multi, ks)
Check whether the ks key_state has finished the key exchange part of the OpenVPN hand shake.
Definition ssl_verify.h:110
static unsigned int min_uint(unsigned int x, unsigned int y)
Definition integer.h:63
static int max_int(int x, int y)
Definition integer.h:89
static SERVICE_STATUS status
Definition interactive.c:53
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)
Definition manage.c:2939
static bool management_enable_def_auth(const struct management *man)
Definition manage.h:459
#define SIZE(x)
Definition basic.h:30
#define dmsg(flags,...)
Definition error.h:148
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
#define MAX_PARMS
Definition options.h:52
time_t now
Definition otime.c:34
bool platform_test_file(const char *filename)
Return true if filename can be opened for read.
Definition platform.c:660
const char * platform_create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
Create a temporary file in directory, returns the filename of the created file.
Definition platform.c:541
const char * platform_gen_path(const char *directory, const char *filename, struct gc_arena *gc)
Put a directory and filename together.
Definition platform.c:594
bool platform_unlink(const char *filename)
Definition platform.c:488
int platform_open(const char *path, int flags, int mode)
Definition platform.c:514
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)
Definition plugin.c:797
bool plugin_defined(const struct plugin_list *pl, const int type)
Definition plugin.c:932
static int plugin_call(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es)
Definition plugin.h:202
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.
Definition push.c:439
#define S_EXITCODE
Instead of returning 1/0 for success/fail, return exit code when between 0 and 255 and -1 otherwise.
Definition run_command.h:49
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.
Definition run_command.h:87
void setenv_link_socket_actual(struct env_set *es, const char *name_prefix, const struct link_socket_actual *act, const unsigned int flags)
Definition socket.c:3130
#define SA_IP_PORT
Definition socket.h:411
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.
Definition ssl_common.h:658
#define KEY_SCAN_SIZE
Definition ssl_common.h:555
auth_deferred_result
Definition ssl_common.h:168
@ ACF_PENDING
deferred auth still pending
Definition ssl_common.h:169
@ ACF_SUCCEEDED
deferred auth has suceeded
Definition ssl_common.h:170
@ ACF_FAILED
deferred auth has failed
Definition ssl_common.h:172
@ ACF_DISABLED
deferred auth is not used
Definition ssl_common.h:171
#define AUTH_TOKEN_EXPIRED
Auth-token sent from client has expired.
Definition ssl_common.h:660
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.
Definition ssl_common.h:705
#define SSLF_AUTH_USER_PASS_OPTIONAL
Definition ssl_common.h:418
@ KS_AUTH_TRUE
Key state is authenticated.
Definition ssl_common.h:151
@ KS_AUTH_FALSE
Key state is not authenticated
Definition ssl_common.h:148
@ KS_AUTH_DEFERRED
Key state authentication is being deferred, by async auth.
Definition ssl_common.h:149
#define SSLF_CRL_VERIFY_DIR
Definition ssl_common.h:420
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.
Definition ssl_common.h:728
#define SSLF_USERNAME_AS_COMMON_NAME
Definition ssl_common.h:417
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...
Definition ssl_util.c:32
SSL utility functions.
static result_t verify_cert_call_command(const char *verify_command, struct env_set *es, int cert_depth, char *subject)
Definition ssl_verify.c:514
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)
Definition ssl_verify.c:403
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.
Definition ssl_verify.c:958
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...
Definition ssl_verify.c:982
static struct cert_hash_set * cert_hash_copy(const struct cert_hash_set *chs)
Definition ssl_verify.c:269
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.
Definition ssl_verify.c:840
#define KMDA_SUCCESS
static result_t verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert, const char *subject, int cert_depth)
Definition ssl_verify.c:548
#define KMDA_DEF
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)
Definition ssl_verify.c:468
static void tls_deauthenticate(struct tls_multi *multi)
Definition ssl_verify.c:73
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.
Definition ssl_verify.c:232
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.
Definition ssl_verify.c:290
static result_t verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert, const char *subject, const char *common_name)
Definition ssl_verify.c:327
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
Definition ssl_verify.c:590
void tls_lock_common_name(struct tls_multi *multi)
Locks the common name field for the given tunnel.
Definition ssl_verify.c:139
static enum auth_deferred_result man_def_auth_test(const struct key_state *ks)
Definition ssl_verify.c:822
#define KMDA_UNDEF
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)
Definition ssl_verify.c:152
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.
Definition ssl_verify.c:891
const char * tls_username(const struct tls_multi *multi, const bool null)
Returns the username field for the given tunnel.
Definition ssl_verify.c:175
#define KMDA_ERROR
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.
Definition ssl_verify.c:808
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)
Definition ssl_verify.c:481
#define TLS_USERNAME_LEN
Maximum length of common name.
Definition ssl_verify.c:52
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)
Definition ssl_verify.c:303
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)
Definition ssl_verify.c:55
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Definition ssl_verify.c:197
static void setenv_untrusted(struct tls_session *session)
Definition ssl_verify.c:64
const char * tls_common_name(const struct tls_multi *multi, const bool null)
Returns the common name field for the given tunnel.
Definition ssl_verify.c:114
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)
Definition ssl_verify.c:92
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.
Definition ssl_verify.c:458
void cert_hash_free(struct cert_hash_set *chs)
Frees the given set of certificate hashes.
Definition ssl_verify.c:218
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.
Definition ssl_verify.c:854
static bool set_verify_user_pass_env(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Control Channel Verification Module.
tls_auth_status
Definition ssl_verify.h:70
@ TLS_AUTHENTICATION_DEFERRED
Definition ssl_verify.h:73
@ TLS_AUTHENTICATION_SUCCEEDED
Definition ssl_verify.h:71
@ TLS_AUTHENTICATION_FAILED
Definition ssl_verify.h:72
#define VERIFY_X509_SUBJECT_DN
Definition ssl_verify.h:65
#define VERIFY_X509_SUBJECT_RDN
Definition ssl_verify.h:66
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:232
#define VERIFY_X509_NONE
Definition ssl_verify.h:64
#define VERIFY_X509_SUBJECT_RDN_PREFIX
Definition ssl_verify.h:67
#define MAX_CERT_DEPTH
Maximum certificate depth we will allow.
Definition ssl_verify.h:52
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:228
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Definition ssl_verify.h:230
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)
Definition test_pkcs11.c:69
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
result_t
Result of verification function.
@ FAILURE
@ SUCCESS
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,...)
Definition status.c:222
struct status_output * status_open(const char *filename, const int refresh_freq, const int msglevel, const struct virtual_output *vout, const unsigned int flags)
Definition status.c:61
bool status_close(struct status_output *so)
Definition status.c:188
#define STATUS_OUTPUT_WRITE
Definition status.h:51
Definition argv.h:35
char * auth_failed_reason_file
Definition ssl_common.h:162
struct buffer_entry * next
Definition buffer.h:1117
struct buffer_entry * head
Definition buffer.h:1122
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int capacity
Size in bytes of memory allocated by malloc().
Definition buffer.h:62
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Structure containing the hashes for a full certificate chain.
Definition ssl_verify.h:60
struct cert_hash * ch[MAX_CERT_DEPTH]
Array of certificate hashes.
Definition ssl_verify.h:61
Structure containing the hash for a single certificate.
Definition ssl_verify.h:55
unsigned char sha256_hash[256/8]
Definition ssl_verify.h:56
char * string
Definition env_set.h:38
struct env_item * next
Definition env_set.h:39
struct env_item * list
Definition env_set.h:44
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Security parameter state of one TLS and data channel key session.
Definition ssl_common.h:200
unsigned int auth_token_state_flags
The state of the auth-token sent from the client.
Definition ssl_common.h:203
struct auth_deferred_status plugin_auth
Definition ssl_common.h:260
unsigned int mda_key_id
Definition ssl_common.h:255
struct auth_deferred_status script_auth
Definition ssl_common.h:261
enum auth_deferred_result mda_status
Definition ssl_common.h:256
enum ks_auth_state authenticated
Definition ssl_common.h:251
time_t auth_deferred_expire
Definition ssl_common.h:252
Security parameter state for a single VPN tunnel.
Definition ssl_common.h:597
char * auth_token_initial
The first auth-token we sent to a client.
Definition ssl_common.h:654
char * peer_info
Definition ssl_common.h:649
char * locked_username
Definition ssl_common.h:630
unsigned int tas_cache_num_updates
The number of times we updated the cache.
Definition ssl_common.h:638
struct tls_session session[TM_SIZE]
Array of tls_session objects representing control channel sessions with the remote peer.
Definition ssl_common.h:681
struct cert_hash_set * locked_cert_hash_set
Definition ssl_common.h:631
time_t tas_cache_last_update
Time of last when we updated the cached state of tls_authentication_status deferred files.
Definition ssl_common.h:635
char * locked_cn
Definition ssl_common.h:629
char * client_reason
Definition ssl_common.h:643
char * auth_token
If server sends a generated auth-token, this is the token to use for future user/pass authentications...
Definition ssl_common.h:650
struct env_set * es
Definition ssl_common.h:405
unsigned remote_cert_ku[MAX_PARMS]
Definition ssl_common.h:348
const char * tmp_dir
Definition ssl_common.h:387
int verify_hash_depth
Definition ssl_common.h:351
const struct plugin_list * plugins
Definition ssl_common.h:407
const char * export_peer_cert_dir
Definition ssl_common.h:388
const char * verify_command
Definition ssl_common.h:342
struct verify_hash_list * verify_hash
Definition ssl_common.h:350
char * x509_username_field[2]
Definition ssl_common.h:357
int verify_x509_type
Definition ssl_common.h:343
const char * verify_x509_name
Definition ssl_common.h:344
const struct x509_track * x509_track
Definition ssl_common.h:432
unsigned int ssl_flags
Definition ssl_common.h:426
hash_algo_type verify_hash_algo
Definition ssl_common.h:353
const char * crl_file
Definition ssl_common.h:345
const char * remote_cert_eku
Definition ssl_common.h:349
Security parameter state of a single session within a VPN tunnel.
Definition ssl_common.h:480
struct key_state key[KS_SIZE]
Definition ssl_common.h:515
struct cert_hash_set * cert_hash_set
Definition ssl_common.h:508
char * common_name
Definition ssl_common.h:506
bool protected
Definition misc.h:63
char password[USER_PASS_LEN]
Definition misc.h:73
char username[USER_PASS_LEN]
Definition misc.h:72
struct verify_hash_list * next
Definition options.h:245
uint8_t hash[SHA256_DIGEST_LENGTH]
Definition options.h:244
#define PATH_SEPARATOR
Definition syshead.h:426
struct env_set * es
static int cleanup(void **state)
struct gc_arena gc
Definition test_ssl.c:155