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