When using the chroot option, the init_ssl function can be called before
entering the chroot or, when OpenVPN receives a SIGHUP, afterwards. This
commit ensures that OpenVPN tries to open the correct path for the CRL
file in either situation.
This commit does not address key and certificate files. For these, the
--persist-key option should be used.
Signed-off-by: Max Fillinger <maximilian.fillinger@foxcrypto.com>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20210415091248.18149-1-maximilian.fillinger@foxcrypto.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22117.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 21a0b2494e7f4f1c6325b2972743158acad4f394)
... | ... |
@@ -2734,7 +2734,7 @@ do_init_crypto_tls_c1(struct context *c) |
2734 | 2734 |
* Initialize the OpenSSL library's global |
2735 | 2735 |
* SSL context. |
2736 | 2736 |
*/ |
2737 |
- init_ssl(options, &(c->c1.ks.ssl_ctx)); |
|
2737 |
+ init_ssl(options, &(c->c1.ks.ssl_ctx), c->c0 && c->c0->uid_gid_chroot_set); |
|
2738 | 2738 |
if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx)) |
2739 | 2739 |
{ |
2740 | 2740 |
#if P2MP |
... | ... |
@@ -787,3 +787,14 @@ get_num_elements(const char *string, char delimiter) |
787 | 787 |
|
788 | 788 |
return element_count; |
789 | 789 |
} |
790 |
+ |
|
791 |
+struct buffer |
|
792 |
+prepend_dir(const char *dir, const char *path, struct gc_arena *gc) |
|
793 |
+{ |
|
794 |
+ size_t len = strlen(dir) + strlen(PATH_SEPARATOR_STR) + strlen(path) + 1; |
|
795 |
+ struct buffer combined_path = alloc_buf_gc(len, gc); |
|
796 |
+ buf_printf(&combined_path, "%s%s%s", dir, PATH_SEPARATOR_STR, path); |
|
797 |
+ ASSERT(combined_path.len > 0); |
|
798 |
+ |
|
799 |
+ return combined_path; |
|
800 |
+} |
... | ... |
@@ -197,4 +197,10 @@ void output_peer_info_env(struct env_set *es, const char *peer_info); |
197 | 197 |
int |
198 | 198 |
get_num_elements(const char *string, char delimiter); |
199 | 199 |
|
200 |
+/** |
|
201 |
+ * Prepend a directory to a path. |
|
202 |
+ */ |
|
203 |
+struct buffer |
|
204 |
+prepend_dir(const char *dir, const char *path, struct gc_arena *gc); |
|
205 |
+ |
|
200 | 206 |
#endif /* ifndef MISC_H */ |
... | ... |
@@ -3328,14 +3328,8 @@ check_file_access_chroot(const char *chroot, const int type, const char *file, c |
3328 | 3328 |
{ |
3329 | 3329 |
struct gc_arena gc = gc_new(); |
3330 | 3330 |
struct buffer chroot_file; |
3331 |
- int len = 0; |
|
3332 |
- |
|
3333 |
- /* Build up a new full path including chroot directory */ |
|
3334 |
- len = strlen(chroot) + strlen(PATH_SEPARATOR_STR) + strlen(file) + 1; |
|
3335 |
- chroot_file = alloc_buf_gc(len, &gc); |
|
3336 |
- buf_printf(&chroot_file, "%s%s%s", chroot, PATH_SEPARATOR_STR, file); |
|
3337 |
- ASSERT(chroot_file.len > 0); |
|
3338 | 3331 |
|
3332 |
+ chroot_file = prepend_dir(chroot, file, &gc); |
|
3339 | 3333 |
ret = check_file_access(type, BSTR(&chroot_file), mode, opt); |
3340 | 3334 |
gc_free(&gc); |
3341 | 3335 |
} |
... | ... |
@@ -583,7 +583,7 @@ tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, |
583 | 583 |
* All files are in PEM format. |
584 | 584 |
*/ |
585 | 585 |
void |
586 |
-init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) |
|
586 |
+init_ssl(const struct options *options, struct tls_root_ctx *new_ctx, bool in_chroot) |
|
587 | 587 |
{ |
588 | 588 |
ASSERT(NULL != new_ctx); |
589 | 589 |
|
... | ... |
@@ -701,7 +701,24 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) |
701 | 701 |
/* Read CRL */ |
702 | 702 |
if (options->crl_file && !(options->ssl_flags & SSLF_CRL_VERIFY_DIR)) |
703 | 703 |
{ |
704 |
- tls_ctx_reload_crl(new_ctx, options->crl_file, options->crl_file_inline); |
|
704 |
+ /* If we're running with the chroot option, we may run init_ssl() before |
|
705 |
+ * and after chroot-ing. We can use the crl_file path as-is if we're |
|
706 |
+ * not going to chroot, or if we already are inside the chroot. |
|
707 |
+ * |
|
708 |
+ * If we're going to chroot later, we need to prefix the path of the |
|
709 |
+ * chroot directory to crl_file. |
|
710 |
+ */ |
|
711 |
+ if (!options->chroot_dir || in_chroot || options->crl_file_inline) |
|
712 |
+ { |
|
713 |
+ tls_ctx_reload_crl(new_ctx, options->crl_file, options->crl_file_inline); |
|
714 |
+ } |
|
715 |
+ else |
|
716 |
+ { |
|
717 |
+ struct gc_arena gc = gc_new(); |
|
718 |
+ struct buffer crl_file_buf = prepend_dir(options->chroot_dir, options->crl_file, &gc); |
|
719 |
+ tls_ctx_reload_crl(new_ctx, BSTR(&crl_file_buf), options->crl_file_inline); |
|
720 |
+ gc_free(&gc); |
|
721 |
+ } |
|
705 | 722 |
} |
706 | 723 |
|
707 | 724 |
/* Once keys and cert are loaded, load ECDH parameters */ |
... | ... |
@@ -154,7 +154,7 @@ void free_ssl_lib(void); |
154 | 154 |
* Build master SSL context object that serves for the whole of OpenVPN |
155 | 155 |
* instantiation |
156 | 156 |
*/ |
157 |
-void init_ssl(const struct options *options, struct tls_root_ctx *ctx); |
|
157 |
+void init_ssl(const struct options *options, struct tls_root_ctx *ctx, bool in_chroot); |
|
158 | 158 |
|
159 | 159 |
/** @addtogroup control_processor |
160 | 160 |
* @{ */ |