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-2018 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.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 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34 
35 #include "syshead.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 
51 #define TLS_USERNAME_LEN 64
52 
53 static void
55 {
56  string_mod(str, CC_PRINT, CC_CRLF, '_');
57 }
58 
59 /*
60  * Export the untrusted IP address and port to the environment
61  */
62 static void
64 {
65  setenv_link_socket_actual(session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT);
66 }
67 
68 /*
69  * Remove authenticated state from all sessions in the given tunnel
70  */
71 static void
73 {
74  if (multi)
75  {
76  wipe_auth_token(multi);
77  for (int i = 0; i < TM_SIZE; ++i)
78  {
79  for (int j = 0; j < KS_SIZE; ++j)
80  {
81  multi->session[i].key[j].authenticated = KS_AUTH_FALSE;
82  }
83  }
84  }
85 }
86 
87 /*
88  * Set the given session's common_name
89  */
90 static void
91 set_common_name(struct tls_session *session, const char *common_name)
92 {
93  if (session->common_name)
94  {
95  free(session->common_name);
96  session->common_name = NULL;
97 #ifdef ENABLE_PF
98  session->common_name_hashval = 0;
99 #endif
100  }
101  if (common_name)
102  {
103  /* FIXME: Last alloc will never be freed */
104  session->common_name = string_alloc(common_name, NULL);
105 #ifdef ENABLE_PF
106  {
107  const uint32_t len = (uint32_t) strlen(common_name);
108  if (len)
109  {
110  session->common_name_hashval = hash_func((const uint8_t *)common_name, len+1, 0);
111  }
112  else
113  {
114  session->common_name_hashval = 0;
115  }
116  }
117 #endif
118  }
119 }
120 
121 /*
122  * Retrieve the common name for the given tunnel's active session. If the
123  * common name is NULL or empty, return NULL if null is true, or "UNDEF" if
124  * null is false.
125  */
126 const char *
127 tls_common_name(const struct tls_multi *multi, const bool null)
128 {
129  const char *ret = NULL;
130  if (multi)
131  {
132  ret = multi->session[TM_ACTIVE].common_name;
133  }
134  if (ret && strlen(ret))
135  {
136  return ret;
137  }
138  else if (null)
139  {
140  return NULL;
141  }
142  else
143  {
144  return "UNDEF";
145  }
146 }
147 
148 /*
149  * Lock the common name for the given tunnel.
150  */
151 void
153 {
154  const char *cn = multi->session[TM_ACTIVE].common_name;
155  if (cn && !multi->locked_cn)
156  {
157  multi->locked_cn = string_alloc(cn, NULL);
158  }
159 }
160 
161 /*
162  * Lock the username for the given tunnel
163  */
164 static bool
165 tls_lock_username(struct tls_multi *multi, const char *username)
166 {
167  if (multi->locked_username)
168  {
169  if (!username || strcmp(username, multi->locked_username))
170  {
171  msg(D_TLS_ERRORS, "TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled",
172  multi->locked_username,
173  np(username));
174 
175  /* disable the tunnel */
176  tls_deauthenticate(multi);
177  return false;
178  }
179  }
180  else
181  {
182  if (username)
183  {
184  multi->locked_username = string_alloc(username, NULL);
185  }
186  }
187  return true;
188 }
189 
190 const char *
191 tls_username(const struct tls_multi *multi, const bool null)
192 {
193  const char *ret = NULL;
194  if (multi)
195  {
196  ret = multi->locked_username;
197  }
198  if (ret && strlen(ret))
199  {
200  return ret;
201  }
202  else if (null)
203  {
204  return NULL;
205  }
206  else
207  {
208  return "UNDEF";
209  }
210 }
211 
212 void
213 cert_hash_remember(struct tls_session *session, const int error_depth,
214  const struct buffer *cert_hash)
215 {
216  if (error_depth >= 0 && error_depth < MAX_CERT_DEPTH)
217  {
218  if (!session->cert_hash_set)
219  {
220  ALLOC_OBJ_CLEAR(session->cert_hash_set, struct cert_hash_set);
221  }
222  if (!session->cert_hash_set->ch[error_depth])
223  {
224  ALLOC_OBJ(session->cert_hash_set->ch[error_depth], struct cert_hash);
225  }
226 
227  struct cert_hash *ch = session->cert_hash_set->ch[error_depth];
228  ASSERT(sizeof(ch->sha256_hash) == BLEN(cert_hash));
229  memcpy(ch->sha256_hash, BPTR(cert_hash), sizeof(ch->sha256_hash));
230  }
231 }
232 
233 void
235 {
236  if (chs)
237  {
238  int i;
239  for (i = 0; i < MAX_CERT_DEPTH; ++i)
240  {
241  free(chs->ch[i]);
242  }
243  free(chs);
244  }
245 }
246 
247 bool
248 cert_hash_compare(const struct cert_hash_set *chs1, const struct cert_hash_set *chs2)
249 {
250  if (chs1 && chs2)
251  {
252  int i;
253  for (i = 0; i < MAX_CERT_DEPTH; ++i)
254  {
255  const struct cert_hash *ch1 = chs1->ch[i];
256  const struct cert_hash *ch2 = chs2->ch[i];
257 
258  if (!ch1 && !ch2)
259  {
260  continue;
261  }
262  else if (ch1 && ch2 && !memcmp(ch1->sha256_hash, ch2->sha256_hash,
263  sizeof(ch1->sha256_hash)))
264  {
265  continue;
266  }
267  else
268  {
269  return false;
270  }
271  }
272  return true;
273  }
274  else if (!chs1 && !chs2)
275  {
276  return true;
277  }
278  else
279  {
280  return false;
281  }
282 }
283 
284 static struct cert_hash_set *
285 cert_hash_copy(const struct cert_hash_set *chs)
286 {
287  struct cert_hash_set *dest = NULL;
288  if (chs)
289  {
290  int i;
291  ALLOC_OBJ_CLEAR(dest, struct cert_hash_set);
292  for (i = 0; i < MAX_CERT_DEPTH; ++i)
293  {
294  const struct cert_hash *ch = chs->ch[i];
295  if (ch)
296  {
297  ALLOC_OBJ(dest->ch[i], struct cert_hash);
298  memcpy(dest->ch[i]->sha256_hash, ch->sha256_hash,
299  sizeof(dest->ch[i]->sha256_hash));
300  }
301  }
302  }
303  return dest;
304 }
305 void
307 {
308  const struct cert_hash_set *chs = multi->session[TM_ACTIVE].cert_hash_set;
309  if (chs && !multi->locked_cert_hash_set)
310  {
311  multi->locked_cert_hash_set = cert_hash_copy(chs);
312  }
313 }
314 
315 /*
316  * Returns the string associated with the given certificate type.
317  */
318 static const char *
320 {
321  switch (type)
322  {
324  return "SERVER";
325 
327  return "CLIENT";
328 
329  default:
330  return "?";
331  }
332 }
333 
334 /*
335  * Verify the peer's certificate fields.
336  *
337  * @param opt the tls options to verify against
338  * @param peer_cert the peer's certificate
339  * @param subject the peer's extracted subject name
340  * @param subject the peer's extracted common name
341  */
342 static result_t
343 verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
344  const char *subject, const char *common_name)
345 {
346  /* verify certificate nsCertType */
347  if (opt->ns_cert_type != NS_CERT_CHECK_NONE)
348  {
349  if (SUCCESS == x509_verify_ns_cert_type(peer_cert, opt->ns_cert_type))
350  {
351  msg(D_HANDSHAKE, "VERIFY OK: nsCertType=%s",
353  }
354  else
355  {
356  msg(D_HANDSHAKE, "VERIFY nsCertType ERROR: %s, require nsCertType=%s",
357  subject, print_nsCertType(opt->ns_cert_type));
358  return FAILURE; /* Reject connection */
359  }
360  }
361 
362  /* verify certificate ku */
363  if (opt->remote_cert_ku[0] != 0)
364  {
365  if (SUCCESS == x509_verify_cert_ku(peer_cert, opt->remote_cert_ku, MAX_PARMS))
366  {
367  msg(D_HANDSHAKE, "VERIFY KU OK");
368  }
369  else
370  {
371  msg(D_HANDSHAKE, "VERIFY KU ERROR");
372  return FAILURE; /* Reject connection */
373  }
374  }
375 
376  /* verify certificate eku */
377  if (opt->remote_cert_eku != NULL)
378  {
379  if (SUCCESS == x509_verify_cert_eku(peer_cert, opt->remote_cert_eku))
380  {
381  msg(D_HANDSHAKE, "VERIFY EKU OK");
382  }
383  else
384  {
385  msg(D_HANDSHAKE, "VERIFY EKU ERROR");
386  return FAILURE; /* Reject connection */
387  }
388  }
389 
390  /* verify X509 name or username against --verify-x509-[user]name */
392  {
394  && strcmp(opt->verify_x509_name, subject) == 0)
396  && strcmp(opt->verify_x509_name, common_name) == 0)
398  && strncmp(opt->verify_x509_name, common_name,
399  strlen(opt->verify_x509_name)) == 0) )
400  {
401  msg(D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject);
402  }
403  else
404  {
405  msg(D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s",
406  subject, opt->verify_x509_name);
407  return FAILURE; /* Reject connection */
408  }
409  }
410 
411  return SUCCESS;
412 }
413 
414 /*
415  * Export the subject, common_name, and raw certificate fields to the
416  * environment for later verification by scripts and plugins.
417  */
418 static void
419 verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth,
420  const char *subject, const char *common_name,
421  const struct x509_track *x509_track)
422 {
423  char envname[64];
424  char *serial = NULL;
425  struct gc_arena gc = gc_new();
426 
427  /* Save X509 fields in environment */
428  if (x509_track)
429  {
430  x509_setenv_track(x509_track, es, cert_depth, peer_cert);
431  }
432  else
433  {
434  x509_setenv(es, cert_depth, peer_cert);
435  }
436 
437  /* export subject name string as environmental variable */
438  openvpn_snprintf(envname, sizeof(envname), "tls_id_%d", cert_depth);
439  setenv_str(es, envname, subject);
440 
441 #if 0
442  /* export common name string as environmental variable */
443  openvpn_snprintf(envname, sizeof(envname), "tls_common_name_%d", cert_depth);
444  setenv_str(es, envname, common_name);
445 #endif
446 
447  /* export X509 cert fingerprints */
448  {
449  struct buffer sha1 = x509_get_sha1_fingerprint(peer_cert, &gc);
450  struct buffer sha256 = x509_get_sha256_fingerprint(peer_cert, &gc);
451 
452  openvpn_snprintf(envname, sizeof(envname), "tls_digest_%d", cert_depth);
453  setenv_str(es, envname,
454  format_hex_ex(BPTR(&sha1), BLEN(&sha1), 0, 1, ":", &gc));
455 
456  openvpn_snprintf(envname, sizeof(envname), "tls_digest_sha256_%d",
457  cert_depth);
458  setenv_str(es, envname,
459  format_hex_ex(BPTR(&sha256), BLEN(&sha256), 0, 1, ":", &gc));
460  }
461 
462  /* export serial number as environmental variable */
463  serial = backend_x509_get_serial(peer_cert, &gc);
464  openvpn_snprintf(envname, sizeof(envname), "tls_serial_%d", cert_depth);
465  setenv_str(es, envname, serial);
466 
467  /* export serial number in hex as environmental variable */
468  serial = backend_x509_get_serial_hex(peer_cert, &gc);
469  openvpn_snprintf(envname, sizeof(envname), "tls_serial_hex_%d", cert_depth);
470  setenv_str(es, envname, serial);
471 
472  gc_free(&gc);
473 }
474 
475 /*
476  * call --tls-verify plug-in(s)
477  */
478 static result_t
479 verify_cert_call_plugin(const struct plugin_list *plugins, struct env_set *es,
480  int cert_depth, openvpn_x509_cert_t *cert, char *subject)
481 {
483  {
484  int ret;
485  struct argv argv = argv_new();
486 
487  argv_printf(&argv, "%d %s", cert_depth, subject);
488 
489  ret = plugin_call_ssl(plugins, OPENVPN_PLUGIN_TLS_VERIFY, &argv, NULL, es, cert_depth, cert);
490 
491  argv_free(&argv);
492 
493  if (ret == OPENVPN_PLUGIN_FUNC_SUCCESS)
494  {
495  msg(D_HANDSHAKE, "VERIFY PLUGIN OK: depth=%d, %s",
496  cert_depth, subject);
497  }
498  else
499  {
500  msg(D_HANDSHAKE, "VERIFY PLUGIN ERROR: depth=%d, %s",
501  cert_depth, subject);
502  return FAILURE; /* Reject connection */
503  }
504  }
505  return SUCCESS;
506 }
507 
508 static const char *
509 verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, struct gc_arena *gc)
510 {
511  FILE *peercert_file;
512  const char *peercert_filename = "";
513 
514  /* create tmp file to store peer cert */
515  if (!tmp_dir
516  || !(peercert_filename = platform_create_temp_file(tmp_dir, "pcf", gc)))
517  {
518  msg(M_NONFATAL, "Failed to create peer cert file");
519  return NULL;
520  }
521 
522  /* write peer-cert in tmp-file */
523  peercert_file = fopen(peercert_filename, "w+");
524  if (!peercert_file)
525  {
526  msg(M_NONFATAL|M_ERRNO, "Failed to open temporary file: %s",
527  peercert_filename);
528  return NULL;
529  }
530 
531  if (SUCCESS != x509_write_pem(peercert_file, peercert))
532  {
533  msg(M_NONFATAL, "Error writing PEM file containing certificate");
534  (void) platform_unlink(peercert_filename);
535  peercert_filename = NULL;
536  }
537 
538  fclose(peercert_file);
539  return peercert_filename;
540 }
541 
542 
543 /*
544  * run --tls-verify script
545  */
546 static result_t
547 verify_cert_call_command(const char *verify_command, struct env_set *es,
548  int cert_depth, openvpn_x509_cert_t *cert, char *subject, const char *verify_export_cert)
549 {
550  const char *tmp_file = NULL;
551  int ret;
552  struct gc_arena gc = gc_new();
553  struct argv argv = argv_new();
554 
555  setenv_str(es, "script_type", "tls-verify");
556 
557  if (verify_export_cert)
558  {
559  tmp_file = verify_cert_export_cert(cert, verify_export_cert, &gc);
560  if (!tmp_file)
561  {
562  ret = false;
563  goto cleanup;
564  }
565  setenv_str(es, "peer_cert", tmp_file);
566  }
567 
568  argv_parse_cmd(&argv, verify_command);
569  argv_printf_cat(&argv, "%d %s", cert_depth, subject);
570 
571  argv_msg_prefix(D_TLS_DEBUG, &argv, "TLS: executing verify command");
572  ret = openvpn_run_script(&argv, es, 0, "--tls-verify script");
573 
574  if (verify_export_cert)
575  {
576  if (tmp_file)
577  {
578  platform_unlink(tmp_file);
579  }
580  }
581 
582 cleanup:
583  gc_free(&gc);
584  argv_free(&argv);
585 
586  if (ret)
587  {
588  msg(D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s",
589  cert_depth, subject);
590  return SUCCESS;
591  }
592 
593  msg(D_HANDSHAKE, "VERIFY SCRIPT ERROR: depth=%d, %s",
594  cert_depth, subject);
595  return FAILURE; /* Reject connection */
596 }
597 
598 /*
599  * check peer cert against CRL directory
600  */
601 static result_t
602 verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert,
603  const char *subject, int cert_depth)
604 {
605  result_t ret = FAILURE;
606  char fn[256];
607  int fd = -1;
608  struct gc_arena gc = gc_new();
609 
610  char *serial = backend_x509_get_serial(cert, &gc);
611  if (!serial)
612  {
613  msg(D_HANDSHAKE, "VERIFY CRL: depth=%d, %s, serial number is not available",
614  cert_depth, subject);
615  goto cleanup;
616  }
617 
618  if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, OS_SPECIFIC_DIRSEP, serial))
619  {
620  msg(D_HANDSHAKE, "VERIFY CRL: filename overflow");
621  goto cleanup;
622  }
623  fd = platform_open(fn, O_RDONLY, 0);
624  if (fd >= 0)
625  {
626  msg(D_HANDSHAKE, "VERIFY CRL: depth=%d, %s, serial=%s is revoked",
627  cert_depth, subject, serial);
628  goto cleanup;
629  }
630 
631  ret = SUCCESS;
632 
633 cleanup:
634 
635  if (fd != -1)
636  {
637  close(fd);
638  }
639  gc_free(&gc);
640  return ret;
641 }
642 
643 result_t
644 verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
645 {
646  result_t ret = FAILURE;
647  char *subject = NULL;
648  const struct tls_options *opt;
649  struct gc_arena gc = gc_new();
650 
651  opt = session->opt;
652  ASSERT(opt);
653 
654  session->verified = false;
655 
656  /* get the X509 name */
657  subject = x509_get_subject(cert, &gc);
658  if (!subject)
659  {
660  msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
661  "subject string from certificate", cert_depth);
662  goto cleanup;
663  }
664 
665  /* enforce character class restrictions in X509 name */
666  string_mod_remap_name(subject);
667  string_replace_leading(subject, '-', '_');
668 
669  /* extract the username (default is CN) */
670  struct buffer buf = alloc_buf_gc(256, &gc);
671  for (int i = 0; opt->x509_username_field[i] != NULL; i++)
672  {
673  char username[TLS_USERNAME_LEN+1] = {0}; /* null-terminated */
674 
675  if (SUCCESS != backend_x509_get_username(username, sizeof(username),
676  opt->x509_username_field[i], cert))
677  {
678  if (!cert_depth)
679  {
680  msg(D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 "
681  "subject string ('%s') -- note that the field length is "
682  "limited to %d characters",
683  opt->x509_username_field[i],
684  subject,
686  goto cleanup;
687  }
688  break;
689  }
690  if (!buf_printf(&buf, i ? "_%s" : "%s", username))
691  {
692  if (!cert_depth)
693  {
694  msg(D_TLS_ERRORS, "VERIFY ERROR: could not append %s from X509 "
695  "certificate -- note that the username length is "
696  "limited to %d characters",
697  opt->x509_username_field[i],
698  buf.capacity - 1);
699  goto cleanup;
700  }
701  break;
702  }
703  }
704 
705  char *common_name = BSTR(&buf);
706  if (!common_name)
707  {
708  msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
709  "username string from certificate", cert_depth);
710  goto cleanup;
711  }
712 
713  /* enforce character class restrictions in common name */
714  string_mod_remap_name(common_name);
715 
716  /* warn if cert chain is too deep */
717  if (cert_depth >= MAX_CERT_DEPTH)
718  {
719  msg(D_TLS_ERRORS, "TLS Error: Convoluted certificate chain detected with depth [%d] greater than %d", cert_depth, MAX_CERT_DEPTH);
720  goto cleanup; /* Reject connection */
721  }
722 
723  /* verify level 1 cert, i.e. the CA that signed our leaf cert */
724  if (cert_depth == 1 && opt->verify_hash)
725  {
726  struct buffer ca_hash = {0};
727 
728  switch (opt->verify_hash_algo)
729  {
730  case MD_SHA1:
731  ca_hash = x509_get_sha1_fingerprint(cert, &gc);
732  break;
733 
734  case MD_SHA256:
735  ca_hash = x509_get_sha256_fingerprint(cert, &gc);
736  break;
737 
738  default:
739  /* This should normally not happen at all; the algorithm used
740  * is parsed by add_option() [options.c] and set to a predefined
741  * value in an enumerated type. So if this unlikely scenario
742  * happens, consider this a failure
743  */
744  msg(M_WARN, "Unexpected invalid algorithm used with "
745  "--verify-hash (%i)", opt->verify_hash_algo);
746  ret = FAILURE;
747  goto cleanup;
748  }
749 
750  if (memcmp(BPTR(&ca_hash), opt->verify_hash, BLEN(&ca_hash)))
751  {
752  msg(D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed");
753  goto cleanup;
754  }
755  }
756 
757  /* save common name in session object */
758  if (cert_depth == 0)
759  {
760  set_common_name(session, common_name);
761  }
762 
763  session->verify_maxlevel = max_int(session->verify_maxlevel, cert_depth);
764 
765  /* export certificate values to the environment */
766  verify_cert_set_env(opt->es, cert, cert_depth, subject, common_name,
767  opt->x509_track);
768 
769  /* export current untrusted IP */
770  setenv_untrusted(session);
771 
772  /* If this is the peer's own certificate, verify it */
773  if (cert_depth == 0 && SUCCESS != verify_peer_cert(opt, cert, subject, common_name))
774  {
775  goto cleanup;
776  }
777 
778  /* call --tls-verify plug-in(s), if registered */
779  if (SUCCESS != verify_cert_call_plugin(opt->plugins, opt->es, cert_depth, cert, subject))
780  {
781  goto cleanup;
782  }
783 
784  /* run --tls-verify script */
786  opt->es, cert_depth, cert, subject, opt->verify_export_cert))
787  {
788  goto cleanup;
789  }
790 
791  /* check peer cert against CRL */
792  if (opt->crl_file)
793  {
794  if (opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
795  {
796  if (SUCCESS != verify_check_crl_dir(opt->crl_file, cert, subject, cert_depth))
797  {
798  goto cleanup;
799  }
800  }
801  else
802  {
803  if (tls_verify_crl_missing(opt))
804  {
805  msg(D_TLS_ERRORS, "VERIFY ERROR: CRL not loaded");
806  goto cleanup;
807  }
808  }
809  }
810 
811  msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject);
812  session->verified = true;
813  ret = SUCCESS;
814 
815 cleanup:
816 
817  if (ret != SUCCESS)
818  {
819  tls_clear_error(); /* always? */
820  session->verified = false; /* double sure? */
821  }
822  gc_free(&gc);
823 
824  return ret;
825 }
826 
827 /* ***************************************************************************
828 * Functions for the management of deferred authentication when using
829 * user/password authentication.
830 *************************************************************************** */
831 
832 /* key_state_test_auth_control_file return values,
833  * NOTE: acf_merge indexing depends on these values */
834 #define ACF_UNDEFINED 0
835 #define ACF_SUCCEEDED 1
836 #define ACF_DISABLED 2
837 #define ACF_FAILED 3
838 
839 void
840 auth_set_client_reason(struct tls_multi *multi, const char *client_reason)
841 {
842  free(multi->client_reason);
843  multi->client_reason = NULL;
844 
845  if (client_reason && strlen(client_reason))
846  {
847  multi->client_reason = string_alloc(client_reason, NULL);
848  }
849 }
850 
851 #ifdef ENABLE_MANAGEMENT
852 
853 static inline unsigned int
854 man_def_auth_test(const struct key_state *ks)
855 {
857  {
858  return ks->mda_status;
859  }
860  else
861  {
862  return ACF_DISABLED;
863  }
864 }
865 #endif /* ifdef ENABLE_MANAGEMENT */
866 
867 
868 /*
869  * auth_control_file functions
870  */
871 
872 void
874 {
875  if (ks && ks->auth_control_file)
876  {
878  free(ks->auth_control_file);
879  ks->auth_control_file = NULL;
880  }
881 }
882 
883 static bool
885 {
886  struct gc_arena gc = gc_new();
887 
889  const char *acf = platform_create_temp_file(opt->tmp_dir, "acf", &gc);
890  if (acf)
891  {
892  ks->auth_control_file = string_alloc(acf, NULL);
893  setenv_str(opt->es, "auth_control_file", ks->auth_control_file);
894  }
895 
896  gc_free(&gc);
897  return acf;
898 }
899 
900 static unsigned int
902 {
903  if (ks && ks->auth_control_file)
904  {
905  unsigned int ret = ks->auth_control_status;
906  if (ret == ACF_UNDEFINED)
907  {
908  FILE *fp = fopen(ks->auth_control_file, "r");
909  if (fp)
910  {
911  const int c = fgetc(fp);
912  if (c == '1')
913  {
914  ret = ACF_SUCCEEDED;
915  }
916  else if (c == '0')
917  {
918  ret = ACF_FAILED;
919  }
920  fclose(fp);
921  ks->auth_control_status = ret;
922  }
923  }
924  return ret;
925  }
926  return ACF_DISABLED;
927 }
928 
929 /*
930  * Return current session authentication state. Return
931  * value is TLS_AUTHENTICATION_x.
932  */
933 
934 int
935 tls_authentication_status(struct tls_multi *multi, const int latency)
936 {
937  bool deferred = false;
938  bool success = false;
939  bool active = false;
940 
941  static const unsigned char acf_merge[] =
942  {
943  ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_UNDEFINED */
944  ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_SUCCEEDED */
945  ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_DISABLED */
946  ACF_FAILED, /* s1=ACF_UNDEFINED s2=ACF_FAILED */
947  ACF_UNDEFINED, /* s1=ACF_SUCCEEDED s2=ACF_UNDEFINED */
948  ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_SUCCEEDED */
949  ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_DISABLED */
950  ACF_FAILED, /* s1=ACF_SUCCEEDED s2=ACF_FAILED */
951  ACF_UNDEFINED, /* s1=ACF_DISABLED s2=ACF_UNDEFINED */
952  ACF_SUCCEEDED, /* s1=ACF_DISABLED s2=ACF_SUCCEEDED */
953  ACF_DISABLED, /* s1=ACF_DISABLED s2=ACF_DISABLED */
954  ACF_FAILED, /* s1=ACF_DISABLED s2=ACF_FAILED */
955  ACF_FAILED, /* s1=ACF_FAILED s2=ACF_UNDEFINED */
956  ACF_FAILED, /* s1=ACF_FAILED s2=ACF_SUCCEEDED */
957  ACF_FAILED, /* s1=ACF_FAILED s2=ACF_DISABLED */
958  ACF_FAILED /* s1=ACF_FAILED s2=ACF_FAILED */
959  };
960 
961  if (multi)
962  {
963  int i;
964 
965  if (latency && multi->tas_last && multi->tas_last + latency >= now)
966  {
968  }
969  multi->tas_last = now;
970 
971  for (i = 0; i < KEY_SCAN_SIZE; ++i)
972  {
973  struct key_state *ks = multi->key_scan[i];
974  if (DECRYPT_KEY_ENABLED(multi, ks))
975  {
976  active = true;
977  if (ks->authenticated > KS_AUTH_FALSE)
978  {
979  unsigned int s1 = ACF_DISABLED;
980  unsigned int s2 = ACF_DISABLED;
982 #ifdef ENABLE_MANAGEMENT
983  s2 = man_def_auth_test(ks);
984 #endif
985  ASSERT(s1 < 4 && s2 < 4);
986  switch (acf_merge[(s1<<2) + s2])
987  {
988  case ACF_SUCCEEDED:
989  case ACF_DISABLED:
990  success = true;
992  break;
993 
994  case ACF_UNDEFINED:
995  if (now < ks->auth_deferred_expire)
996  {
997  deferred = true;
998  }
999  break;
1000 
1001  case ACF_FAILED:
1003  break;
1004 
1005  default:
1006  ASSERT(0);
1007  }
1008  }
1009  }
1010  }
1011  }
1012 
1013 #if 0
1014  dmsg(D_TLS_ERRORS, "TAS: a=%d s=%d d=%d", active, success, deferred);
1015 #endif
1016 
1017  if (success)
1018  {
1020  }
1021  else if (!active || deferred)
1022  {
1024  }
1025  else
1026  {
1028  }
1029 }
1030 
1031 #ifdef ENABLE_MANAGEMENT
1032 /*
1033  * For deferred auth, this is where the management interface calls (on server)
1034  * to indicate auth failure/success.
1035  */
1036 bool
1037 tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason)
1038 {
1039  bool ret = false;
1040  if (multi)
1041  {
1042  int i;
1043  auth_set_client_reason(multi, client_reason);
1044  for (i = 0; i < KEY_SCAN_SIZE; ++i)
1045  {
1046  struct key_state *ks = multi->key_scan[i];
1047  if (ks->mda_key_id == mda_key_id)
1048  {
1049  ks->mda_status = auth ? ACF_SUCCEEDED : ACF_FAILED;
1050  ret = true;
1051  }
1052  }
1053  }
1054  return ret;
1055 }
1056 #endif /* ifdef ENABLE_MANAGEMENT */
1057 
1058 
1059 /* ****************************************************************************
1060  * Functions to verify username and password
1061  *
1062  * Authenticate a client using username/password.
1063  * Runs on server.
1064  *
1065  * If you want to add new authentication methods,
1066  * this is the place to start.
1067  *************************************************************************** */
1068 
1069 /*
1070  * Verify the user name and password using a script
1071  */
1072 static bool
1074  const struct user_pass *up)
1075 {
1076  struct gc_arena gc = gc_new();
1077  struct argv argv = argv_new();
1078  const char *tmp_file = "";
1079  bool ret = false;
1080 
1081  /* Set environmental variables prior to calling script */
1082  setenv_str(session->opt->es, "script_type", "user-pass-verify");
1083 
1084  /* format command line */
1086 
1088  {
1089  struct status_output *so;
1090 
1091  tmp_file = platform_create_temp_file(session->opt->tmp_dir, "up",
1092  &gc);
1093  if (tmp_file)
1094  {
1095  so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE);
1096  status_printf(so, "%s", up->username);
1097  status_printf(so, "%s", up->password);
1098  if (!status_close(so))
1099  {
1100  msg(D_TLS_ERRORS, "TLS Auth Error: could not write username/password to file: %s",
1101  tmp_file);
1102  goto done;
1103  }
1104  /* pass temp file name to script */
1105  argv_printf_cat(&argv, "%s", tmp_file);
1106  }
1107  else
1108  {
1109  msg(D_TLS_ERRORS, "TLS Auth Error: could not create write "
1110  "username/password to temp file");
1111  }
1112  }
1113  else
1114  {
1115  setenv_str(session->opt->es, "password", up->password);
1116  }
1117 
1118  /* call command */
1119  ret = openvpn_run_script(&argv, session->opt->es, 0,
1120  "--auth-user-pass-verify");
1121 
1123  {
1124  setenv_del(session->opt->es, "password");
1125  }
1126 done:
1127  if (tmp_file && strlen(tmp_file) > 0)
1128  {
1129  platform_unlink(tmp_file);
1130  }
1131 
1132  argv_free(&argv);
1133  gc_free(&gc);
1134  return ret;
1135 }
1136 
1137 /*
1138  * Verify the username and password using a plugin
1139  */
1140 static int
1142  const struct user_pass *up)
1143 {
1144  int retval = OPENVPN_PLUGIN_FUNC_ERROR;
1145  struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1146 
1147  /* set password in private env space */
1148  setenv_str(session->opt->es, "password", up->password);
1149 
1150  /* generate filename for deferred auth control file */
1151  if (!key_state_gen_auth_control_file(ks, session->opt))
1152  {
1153  msg(D_TLS_ERRORS, "TLS Auth Error (%s): "
1154  "could not create deferred auth control file", __func__);
1155  return retval;
1156  }
1157 
1158  /* call command */
1159  retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es);
1160 
1161  /* purge auth control filename (and file itself) for non-deferred returns */
1162  if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED)
1163  {
1165  }
1166 
1167  setenv_del(session->opt->es, "password");
1168 
1169  return retval;
1170 }
1171 
1172 
1173 #ifdef ENABLE_MANAGEMENT
1174 /*
1175  * management deferred internal ssl_verify.c status codes
1176  */
1177 #define KMDA_ERROR 0
1178 #define KMDA_SUCCESS 1
1179 #define KMDA_UNDEF 2
1180 #define KMDA_DEF 3
1181 
1182 static int
1184  struct tls_multi *multi,
1185  const struct user_pass *up)
1186 {
1187  int retval = KMDA_ERROR;
1188  struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1189 
1190  /* set username/password in private env space */
1191  setenv_str(session->opt->es, "password", up->password);
1192 
1193  if (management)
1194  {
1196  }
1197 
1198  setenv_del(session->opt->es, "password");
1199 
1200  retval = KMDA_SUCCESS;
1201 
1202  return retval;
1203 }
1204 #endif /* ifdef ENABLE_MANAGEMENT */
1205 
1206 static bool
1208  struct tls_session *session)
1209 {
1210  /* Is username defined? */
1211  if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username))
1212  {
1213  setenv_str(session->opt->es, "username", up->username);
1214 
1215  /* setenv incoming cert common name for script */
1216  setenv_str(session->opt->es, "common_name", session->common_name);
1217 
1218  /* setenv client real IP address */
1219  setenv_untrusted(session);
1220 
1221  /*
1222  * if we are using auth-gen-token, send also the session id of auth gen token to
1223  * allow the management to figure out if it is a new session or a continued one
1224  */
1225  add_session_token_env(session, multi, up);
1226  return true;
1227  }
1228  else
1229  {
1230  msg(D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username");
1231  return false;
1232  }
1233 }
1234 
1235 /*
1236  * Main username/password verification entry point
1237  *
1238  * Will set session->ks[KS_PRIMARY].authenticated according to
1239  * result of the username/password verification
1240  */
1241 void
1242 verify_user_pass(struct user_pass *up, struct tls_multi *multi,
1243  struct tls_session *session)
1244 {
1245  int s1 = OPENVPN_PLUGIN_FUNC_SUCCESS;
1246  bool s2 = true;
1247  struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1248 
1249 #ifdef ENABLE_MANAGEMENT
1250  int man_def_auth = KMDA_UNDEF;
1251 
1253  {
1254  man_def_auth = KMDA_DEF;
1255  }
1256 #endif
1257 
1258  /* enforce character class restrictions in username/password */
1260  string_mod(up->password, CC_PRINT, CC_CRLF, '_');
1261 
1262  /*
1263  * If auth token succeeds we skip the auth
1264  * methods unless otherwise specified
1265  */
1266  bool skip_auth = false;
1267 
1268  /*
1269  * If server is configured with --auth-gen-token and the client sends
1270  * something that looks like an authentication token, this
1271  * round will be done internally using the token instead of
1272  * calling any external authentication modules.
1273  */
1274  if (session->opt->auth_token_generate && is_auth_token(up->password))
1275  {
1276  multi->auth_token_state_flags = verify_auth_token(up, multi, session);
1277  if (session->opt->auth_token_call_auth)
1278  {
1279  /*
1280  * we do not care about the result here because it is
1281  * the responsibility of the external authentication to
1282  * decide what to do with the result
1283  */
1284  }
1285  else if (multi->auth_token_state_flags == AUTH_TOKEN_HMAC_OK)
1286  {
1287  /*
1288  * We do not want the EXPIRED or EMPTY USER flags here so check
1289  * for equality with AUTH_TOKEN_HMAC_OK
1290  */
1291  msg(M_WARN, "TLS: Username/auth-token authentication "
1292  "succeeded for username '%s'",
1293  up->username);
1294  skip_auth = true;
1295  }
1296  else
1297  {
1298  wipe_auth_token(multi);
1300  msg(M_WARN, "TLS: Username/auth-token authentication "
1301  "failed for username '%s'", up->username);
1302  return;
1303  }
1304  }
1305 
1306  /* Set the environment variables used by all auth variants */
1307  if (!set_verify_user_pass_env(up, multi, session))
1308  {
1309  skip_auth = true;
1311  }
1312 
1313  /* call plugin(s) and/or script */
1314  if (!skip_auth)
1315  {
1316 #ifdef ENABLE_MANAGEMENT
1317  if (man_def_auth==KMDA_DEF)
1318  {
1319  man_def_auth = verify_user_pass_management(session, multi, up);
1320  }
1321 #endif
1323  {
1324  s1 = verify_user_pass_plugin(session, multi, up);
1325  }
1326 
1327  if (session->opt->auth_user_pass_verify_script)
1328  {
1329  s2 = verify_user_pass_script(session, multi, up);
1330  }
1331  }
1332 
1333  /* check sizing of username if it will become our common name */
1334  if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
1335  && strlen(up->username)>TLS_USERNAME_LEN)
1336  {
1337  msg(D_TLS_ERRORS,
1338  "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters",
1341  }
1342  /* auth succeeded? */
1343  if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS
1345  ) && s2
1346 #ifdef ENABLE_MANAGEMENT
1347  && man_def_auth != KMDA_ERROR
1348 #endif
1349  && tls_lock_username(multi, up->username))
1350  {
1352  if (s1 == OPENVPN_PLUGIN_FUNC_DEFERRED)
1353  {
1355  }
1356 #ifdef ENABLE_MANAGEMENT
1357  if (man_def_auth != KMDA_UNDEF)
1358  {
1360  }
1361 #endif
1362  if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
1363  {
1364  set_common_name(session, up->username);
1365  }
1366 
1367  if ((session->opt->auth_token_generate))
1368  {
1369  /*
1370  * If we accepted a (not expired) token, i.e.
1371  * initial auth via token on new connection, we need
1372  * to store the auth-token in multi->auth_token, so
1373  * the initial timestamp and session id can be extracted from it
1374  */
1375  if (!multi->auth_token
1378  {
1379  multi->auth_token = strdup(up->password);
1380  }
1381 
1382  /*
1383  * Server is configured with --auth-gen-token. Generate or renew
1384  * the token.
1385  */
1386  generate_auth_token(up, multi);
1387  }
1388  /*
1389  * Auth token already sent to client, update auth-token on client.
1390  * The initial auth-token is sent as part of the push message, for this
1391  * update we need to schedule an extra push message.
1392  *
1393  * Otherwise the auth-token get pushed out as part of the "normal"
1394  * push-reply
1395  */
1396  if (multi->auth_token_initial)
1397  {
1398  /*
1399  * We do not explicitly schedule the sending of the
1400  * control message here but control message are only
1401  * postponed when the control channel is not yet fully
1402  * established and furthermore since this is called in
1403  * the middle of authentication, there are other messages
1404  * (new data channel keys) that are sent anyway and will
1405  * trigger schedueling
1406  */
1408  }
1409  msg(D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s",
1410  (ks->authenticated == KS_AUTH_DEFERRED) ? "deferred" : "succeeded",
1411  up->username,
1412  (session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
1413  }
1414  else
1415  {
1417  msg(D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
1418  }
1419 }
1420 
1421 void
1423 {
1424  struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */
1425 
1426  /* While it shouldn't really happen, don't allow the common name to be NULL */
1427  if (!session->common_name)
1428  {
1429  set_common_name(session, "");
1430  }
1431 
1432  /* Don't allow the CN to change once it's been locked */
1433  if (ks->authenticated > KS_AUTH_FALSE && multi->locked_cn)
1434  {
1435  const char *cn = session->common_name;
1436  if (cn && strcmp(cn, multi->locked_cn))
1437  {
1438  msg(D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled",
1439  multi->locked_cn,
1440  cn);
1441 
1442  /* change the common name back to its original value and disable the tunnel */
1443  set_common_name(session, multi->locked_cn);
1444  tls_deauthenticate(multi);
1445  }
1446  }
1447 
1448  /* Don't allow the cert hashes to change once they have been locked */
1449  if (ks->authenticated > KS_AUTH_FALSE && multi->locked_cert_hash_set)
1450  {
1451  const struct cert_hash_set *chs = session->cert_hash_set;
1452  if (chs && !cert_hash_compare(chs, multi->locked_cert_hash_set))
1453  {
1454  msg(D_TLS_ERRORS, "TLS Auth Error: TLS object CN=%s client-provided SSL certs unexpectedly changed during mid-session reauth",
1455  session->common_name);
1456 
1457  /* disable the tunnel */
1458  tls_deauthenticate(multi);
1459  }
1460  }
1461 
1462  /* verify --client-config-dir based authentication */
1464  {
1465  struct gc_arena gc = gc_new();
1466 
1467  const char *cn = session->common_name;
1468  const char *path = platform_gen_path(session->opt->client_config_dir_exclusive,
1469  cn, &gc);
1470  if (!cn || !strcmp(cn, CCD_DEFAULT) || !platform_test_file(path))
1471  {
1473  wipe_auth_token(multi);
1474  msg(D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'",
1475  session->common_name,
1476  path ? path : "UNDEF");
1477  }
1478 
1479  gc_free(&gc);
1480  }
1481 }
1482 
1483 void
1485 {
1486  struct env_item *item = es->list;
1487  while (item)
1488  {
1489  struct env_item *next = item->next;
1490  if (item->string
1491  && 0 == strncmp("X509_", item->string, strlen("X509_")))
1492  {
1493  env_set_del(es, item->string);
1494  }
1495  item = next;
1496  }
1497 }
#define M_NONFATAL
Definition: error.h:95
static bool tls_lock_username(struct tls_multi *multi, const char *username)
Definition: ssl_verify.c:165
bool argv_printf_cat(struct argv *argres, const char *format,...)
printf() inspired argv concatenation.
Definition: argv.c:466
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:52
int auth_token_state_flags
The state of the auth-token sent from the client last time.
Definition: ssl_common.h:585
#define VERIFY_X509_SUBJECT_RDN
Definition: ssl_verify.h:65
#define TM_ACTIVE
Active tls_session.
Definition: ssl_common.h:474
const char * tmp_dir
Definition: ssl_common.h:329
Security parameter state of one TLS and data channel key session.
Definition: ssl_common.h:178
struct key_state key[KS_SIZE]
Definition: ssl_common.h:454
const char * crl_file
Definition: ssl_common.h:290
#define SSLF_CRL_VERIFY_DIR
Definition: ssl_common.h:359
static void verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert_depth, const char *subject, const char *common_name, const struct x509_track *x509_track)
Definition: ssl_verify.c:419
#define ALLOC_OBJ(dptr, type)
Definition: buffer.h:1045
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:174
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:685
#define D_TLS_DEBUG
Definition: errlevel.h:163
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition: argv.c:90
#define STATUS_OUTPUT_WRITE
Definition: status.h:51
#define SSLF_USERNAME_AS_COMMON_NAME
Definition: ssl_common.h:356
#define VERIFY_X509_SUBJECT_DN
Definition: ssl_verify.h:64
#define OS_SPECIFIC_DIRSEP
Definition: syshead.h:479
static bool verify_user_pass_script(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
Definition: ssl_verify.c:1073
#define AUTH_TOKEN_EXPIRED
Auth-token sent from client has expired.
Definition: ssl_common.h:575
enum ks_auth_state authenticated
Definition: ssl_common.h:218
struct tls_options * opt
Definition: ssl_common.h:419
int verify_maxlevel
Definition: ssl_common.h:439
#define SSLF_AUTH_USER_PASS_OPTIONAL
Definition: ssl_common.h:357
#define SA_IP_PORT
Definition: socket.h:405
char * auth_token_initial
The first auth-token we sent to a client, for clients that do not update their auth-token (older Open...
Definition: ssl_common.h:569
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1023
bool verified
Definition: ssl_common.h:449
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
#define dmsg
Definition: error.h:174
const char * auth_user_pass_verify_script
Definition: ssl_common.h:327
#define KMDA_SUCCESS
Definition: ssl_verify.c:1178
#define ACF_DISABLED
Definition: ssl_verify.c:836
Security parameter state for a single VPN tunnel.
Definition: ssl_common.h:511
#define NS_CERT_CHECK_CLIENT
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:216
#define D_TLS_ERRORS
Definition: errlevel.h:59
#define CC_PRINT
Definition: buffer.h:915
void send_push_reply_auth_token(struct tls_multi *multi)
Sends a push reply message only containin the auth-token to update the auth-token on the client...
Definition: push.c:530
X509 openvpn_x509_cert_t
int tls_authentication_status(struct tls_multi *multi, const int latency)
Definition: ssl_verify.c:935
const char * client_config_dir_exclusive
Definition: ssl_common.h:341
#define ACF_SUCCEEDED
Definition: ssl_verify.c:835
int verify_x509_type
Definition: ssl_common.h:288
result_t x509_verify_cert_ku(openvpn_x509_cert_t *x509, const unsigned *const expected_ku, int expected_len)
struct cert_hash_set * cert_hash_set
Definition: ssl_common.h:443
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:787
Key state is authenticated.
Definition: ssl_common.h:153
void key_state_rm_auth_control_file(struct key_state *ks)
Remove the given key state&#39;s auth control file, if it exists.
Definition: ssl_verify.c:873
char * x509_username_field[2]
Definition: ssl_common.h:300
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:242
void cert_hash_remember(struct tls_session *session, const int error_depth, const struct buffer *cert_hash)
Definition: ssl_verify.c:213
struct man_def_auth_context * mda_context
Definition: ssl_common.h:367
static const char * verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, struct gc_arena *gc)
Definition: ssl_verify.c:509
static void tls_deauthenticate(struct tls_multi *multi)
Definition: ssl_verify.c:72
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: env_set.c:285
#define MAX_PARMS
Definition: options.h:51
#define TLS_USERNAME_LEN
Maximum length of common name.
Definition: ssl_verify.c:51
#define DECRYPT_KEY_ENABLED(multi, ks)
Check whether the ks key_state is ready to receive data channel packets.
Definition: ssl_verify.h:89
bool auth_token_generate
Generate auth-tokens on successful user/pass auth,seet via options->auth_token_generate.
Definition: ssl_common.h:332
static void string_mod_remap_name(char *str)
Definition: ssl_verify.c:54
static int verify_user_pass_management(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
Definition: ssl_verify.c:1183
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:602
#define ASSERT(x)
Definition: error.h:221
Structure containing the hash for a single certificate.
Definition: ssl_verify.h:54
#define OPENVPN_PLUGIN_FUNC_SUCCESS
struct tls_session session[TM_SIZE]
Array of tls_session objects representing control channel sessions with the remote peer...
Definition: ssl_common.h:597
Structure containing the hashes for a full certificate chain.
Definition: ssl_verify.h:59
bool platform_unlink(const char *filename)
Definition: platform.c:287
void status_printf(struct status_output *so, const char *format,...)
Definition: status.c:224
char username[USER_PASS_LEN]
Definition: misc.h:75
result_t verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
Definition: ssl_verify.c:644
int capacity
Size in bytes of memory allocated by malloc().
Definition: buffer.h:62
void setenv_del(struct env_set *es, const char *name)
Definition: env_set.c:330
static unsigned int key_state_test_auth_control_file(struct key_state *ks)
Definition: ssl_verify.c:901
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:63
#define VERIFY_X509_NONE
Definition: ssl_verify.h:63
#define TLS_AUTHENTICATION_UNDEFINED
Definition: ssl_verify.h:71
bool status_close(struct status_output *so)
Definition: status.c:190
struct key_state * key_scan[KEY_SCAN_SIZE]
List of key_state objects in the order they should be scanned by data channel modules.
Definition: ssl_common.h:519
#define BPTR(buf)
Definition: buffer.h:124
#define AUTH_TOKEN_HMAC_OK
Auth-token sent from client has valid hmac.
Definition: ssl_common.h:573
static const char * print_nsCertType(int type)
Definition: ssl_verify.c:319
unsigned int auth_control_status
Definition: ssl_common.h:225
#define KEY_SCAN_SIZE
Definition: ssl_common.h:496
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:296
#define OPENVPN_PLUGIN_FUNC_DEFERRED
Key state authentication is being deferred, by async auth.
Definition: ssl_common.h:151
#define KS_SIZE
Size of the tls_session.key array.
Definition: ssl_common.h:396
struct env_item * list
Definition: env_set.h:44
#define ACF_FAILED
Definition: ssl_verify.c:837
bool auth_user_pass_verify_script_via_file
Definition: ssl_common.h:328
int platform_open(const char *path, int flags, int mode)
Definition: platform.c:315
#define OPENVPN_PLUGIN_TLS_VERIFY
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:3148
#define OPENVPN_PLUGIN_FUNC_ERROR
static const char * np(const char *str)
Definition: simple.c:108
static struct gc_arena gc_new(void)
Definition: buffer.h:1015
#define KS_PRIMARY
Primary key state index.
Definition: ssl_common.h:392
struct gc_arena gc
Definition: argv.h:36
Key state is not authenticated.
Definition: ssl_common.h:150
unsigned remote_cert_ku[MAX_PARMS]
Definition: ssl_common.h:293
time_t now
Definition: otime.c:36
static int verify_user_pass_plugin(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
Definition: ssl_verify.c:1141
void x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, openvpn_x509_cert_t *x509)
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1050
unsigned int mda_key_id
Definition: ssl_common.h:222
#define ENABLE_MANAGEMENT
Definition: config-msvc.h:14
char * locked_cn
Definition: ssl_common.h:548
bool platform_test_file(const char *filename)
Return true if filename can be opened for read.
Definition: platform.c:461
bool env_set_del(struct env_set *es, const char *str)
Definition: env_set.c:185
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:840
int ns_cert_type
Definition: ssl_common.h:292
#define MAX_CERT_DEPTH
Maximum certificate depth we will allow.
Definition: ssl_verify.h:51
result_t x509_verify_cert_eku(openvpn_x509_cert_t *x509, const char *const expected_oid)
hash_algo_type verify_hash_algo
Definition: ssl_common.h:296
unsigned __int32 uint32_t
Definition: config-msvc.h:157
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:390
#define NS_CERT_CHECK_NONE
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:212
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:262
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:299
unsigned int mda_status
Definition: ssl_common.h:223
struct cert_hash_set * locked_cert_hash_set
Definition: ssl_common.h:550
const char * verify_x509_name
Definition: ssl_common.h:289
static unsigned int man_def_auth_test(const struct key_state *ks)
Definition: ssl_verify.c:854
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
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:248
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:343
const char * platform_gen_path(const char *directory, const char *filename, struct gc_arena *gc)
Put a directory and filename together.
Definition: platform.c:395
const struct plugin_list * plugins
Definition: ssl_common.h:346
struct env_item * next
Definition: env_set.h:39
struct link_socket_actual untrusted_addr
Definition: ssl_common.h:452
#define M_ERRNO
Definition: error.h:99
char * string
Definition: env_set.h:38
#define msg
Definition: error.h:173
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:519
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:2906
const char * verify_export_cert
Definition: ssl_common.h:287
char * client_reason
Definition: ssl_common.h:558
#define VERIFY_X509_SUBJECT_RDN_PREFIX
Definition: ssl_verify.h:66
bool auth_token_call_auth
always call normal authentication
Definition: ssl_common.h:335
char * dest
Definition: compat-lz4.h:686
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
#define TM_SIZE
Size of the tls_multi.session array.
Definition: ssl_common.h:479
#define TLS_AUTHENTICATION_FAILED
Definition: ssl_verify.h:69
static void set_common_name(struct tls_session *session, const char *common_name)
Definition: ssl_verify.c:91
#define KMDA_DEF
Definition: ssl_verify.c:1180
#define CCD_DEFAULT
Definition: common.h:71
static bool key_state_gen_auth_control_file(struct key_state *ks, const struct tls_options *opt)
Definition: ssl_verify.c:884
static void setenv_untrusted(struct tls_session *session)
Definition: ssl_verify.c:63
#define BLEN(buf)
Definition: buffer.h:127
time_t auth_deferred_expire
Definition: ssl_common.h:219
void verify_user_pass(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Verify the given username and password, using either an external script, a plugin, or the management interface.
Definition: ssl_verify.c:1242
time_t tas_last
Definition: ssl_common.h:553
#define D_HANDSHAKE
Definition: errlevel.h:72
static int max_int(int x, int y)
Definition: integer.h:44
bool tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason)
Definition: ssl_verify.c:1037
uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval)
Definition: list.c:589
unsigned __int8 uint8_t
Definition: config-msvc.h:159
#define KMDA_UNDEF
Definition: ssl_verify.c:1179
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1078
result_t x509_verify_ns_cert_type(openvpn_x509_cert_t *cert, const int usage)
struct buffer x509_get_sha1_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate&#39;s SHA1 fingerprint.
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:565
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
bool plugin_defined(const struct plugin_list *pl, const int type)
Definition: plugin.c:901
bool tls_verify_crl_missing(const struct tls_options *opt)
Return true iff a CRL is configured, but is not loaded.
void string_replace_leading(char *str, const char match, const char replace)
Definition: buffer.c:1129
const char * verify_command
Definition: ssl_common.h:286
Security parameter state of a single session within a VPN tunnel.
Definition: ssl_common.h:416
char * auth_control_file
Definition: ssl_common.h:227
Definition: misc.h:63
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
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:479
#define TLS_AUTHENTICATION_SUCCEEDED
Definition: ssl_verify.h:68
static bool set_verify_user_pass_env(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Definition: ssl_verify.c:1207
static bool management_enable_def_auth(const struct management *man)
Definition: manage.h:471
result_t x509_write_pem(FILE *peercert_file, openvpn_x509_cert_t *peercert)
char * locked_username
Definition: ssl_common.h:549
char * common_name
Definition: ssl_common.h:441
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:127
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:90
uint8_t * verify_hash
Definition: ssl_common.h:295
#define M_WARN
Definition: error.h:96
void tls_clear_error(void)
Clear the underlying SSL library&#39;s error state.
Definition: ssl_openssl.c:102
const char * tls_username(const struct tls_multi *multi, const bool null)
Returns the username field for the given tunnel.
Definition: ssl_verify.c:191
#define free
Definition: cmocka.c:1850
void tls_x509_clear_env(struct env_set *es)
Remove any X509_ env variables from env_set es.
Definition: ssl_verify.c:1484
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:485
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
void tls_lock_common_name(struct tls_multi *multi)
Locks the common name field for the given tunnel.
Definition: ssl_verify.c:152
void tls_lock_cert_hash_set(struct tls_multi *multi)
Locks the certificate hash set used in the given tunnel.
Definition: ssl_verify.c:306
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:342
#define TLS_AUTHENTICATION_DEFERRED
Definition: ssl_verify.h:70
void cert_hash_free(struct cert_hash_set *chs)
Frees the given set of certificate hashes.
Definition: ssl_verify.c:234
#define BSTR(buf)
Definition: buffer.h:129
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition: argv.c:104
struct buffer x509_get_sha256_fingerprint(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Retrieve the certificate&#39;s SHA256 fingerprint.
char password[USER_PASS_LEN]
Definition: misc.h:76
static struct cert_hash_set * cert_hash_copy(const struct cert_hash_set *chs)
Definition: ssl_verify.c:285
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...
Definition: ssl_verify.c:1422
Definition: argv.h:35
#define CC_CRLF
Definition: buffer.h:944
#define KMDA_ERROR
Definition: ssl_verify.c:1177
const struct x509_track * x509_track
Definition: ssl_common.h:370
static bool openvpn_run_script(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *hook)
Definition: run_command.h:57
#define ACF_UNDEFINED
Definition: ssl_verify.c:834
unsigned int ssl_flags
Definition: ssl_common.h:364
static result_t verify_cert_call_command(const char *verify_command, struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert, char *subject, const char *verify_export_cert)
Definition: ssl_verify.c:547
struct env_set * es
Definition: ssl_common.h:344
struct cert_hash * ch[MAX_CERT_DEPTH]
Array of certificate hashes.
Definition: ssl_verify.h:60
void x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
result_t
Result of verification function.
const char * remote_cert_eku
Definition: ssl_common.h:294
result_t backend_x509_get_username(char *common_name, int cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
unsigned char sha256_hash[256/8]
Definition: ssl_verify.h:55
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition: argv.c:442
#define NS_CERT_CHECK_SERVER
Do not perform Netscape certificate type verification.
Definition: ssl_verify.h:214
static bool is_auth_token(const char *password)
Return if the password string has the format of a password.
Definition: auth_token.h:127