diff --git a/include/fluent-bit/flb_output.h b/include/fluent-bit/flb_output.h index 76ac32b9a8f..848d8bde538 100644 --- a/include/fluent-bit/flb_output.h +++ b/include/fluent-bit/flb_output.h @@ -369,6 +369,10 @@ struct flb_output_instance { char *tls_min_version; /* Minimum protocol version of TLS */ char *tls_max_version; /* Maximum protocol version of TLS */ char *tls_ciphers; /* TLS ciphers */ +# if defined(FLB_SYSTEM_WINDOWS) + char *tls_win_certstore_name; /* CertStore Name (Windows) */ + int tls_win_use_enterprise_certstore; /* Use enterprise CertStore */ +# endif #endif /* diff --git a/include/fluent-bit/tls/flb_tls.h b/include/fluent-bit/tls/flb_tls.h index 6f1c857eb11..c7165538e95 100644 --- a/include/fluent-bit/tls/flb_tls.h +++ b/include/fluent-bit/tls/flb_tls.h @@ -92,6 +92,11 @@ struct flb_tls_backend { int (*net_write) (struct flb_tls_session *, const void *data, size_t len); int (*net_handshake) (struct flb_tls *, char *, void *); + +#if defined(FLB_SYSTEM_WINDOWS) + int (*set_certstore_name)(struct flb_tls *tls, const char *certstore_name); + int (*set_use_enterprise_store)(struct flb_tls *tls, int use_enterprise); +#endif }; /* Main TLS context */ @@ -101,6 +106,10 @@ struct flb_tls { char *vhost; /* Virtual hostname for SNI */ int mode; /* Client or Server */ int verify_hostname; /* Verify hostname */ +#if defined(FLB_SYSTEM_WINDOWS) + char *certstore_name; /* Windows CertStore Name */ + int use_enterprise_store; /* Use Enterprise store or not */ +#endif /* Bakend library for TLS */ void *ctx; /* TLS context created */ @@ -122,6 +131,10 @@ int flb_tls_destroy(struct flb_tls *tls); int flb_tls_set_alpn(struct flb_tls *tls, const char *alpn); int flb_tls_set_verify_hostname(struct flb_tls *tls, int verify_hostname); +#if defined(FLB_SYSTEM_WINDOWS) +int flb_tls_set_certstore_name(struct flb_tls *tls, const char *certstore_name); +int flb_tls_set_use_enterprise_store(struct flb_tls *tls, int use_enterprise); +#endif int flb_tls_load_system_certificates(struct flb_tls *tls); int flb_tls_set_minmax_proto(struct flb_tls *tls, diff --git a/src/flb_output.c b/src/flb_output.c index cb3cd1b6b0c..6fc925f0d83 100644 --- a/src/flb_output.c +++ b/src/flb_output.c @@ -83,6 +83,16 @@ struct flb_config_map output_global_properties[] = { "Accepted values: a positive integer, 'no_limits', 'false', or 'off' to disable retry limits, " "or 'no_retries' to disable retries entirely." }, + { + FLB_CONFIG_MAP_STR, "tls.windows.certstore_name", NULL, + 0, FLB_FALSE, 0, + "Sets the certstore name on an output (Windows)" + }, + { + FLB_CONFIG_MAP_STR, "tls.windows.use_enterprise_store", NULL, + 0, FLB_FALSE, 0, + "Sets whether using enterprise certstore or not on an output (Windows)" + }, {0} }; @@ -174,6 +184,11 @@ static void flb_output_free_properties(struct flb_output_instance *ins) if (ins->tls_ciphers) { flb_sds_destroy(ins->tls_ciphers); } +# if defined(FLB_SYSTEM_WINDOWS) + if (ins->tls_win_certstore_name) { + flb_sds_destroy(ins->tls_win_certstore_name); + } +# endif #endif } @@ -751,6 +766,10 @@ struct flb_output_instance *flb_output_new(struct flb_config *config, instance->tls_crt_file = NULL; instance->tls_key_file = NULL; instance->tls_key_passwd = NULL; +# if defined(FLB_SYSTEM_WINDOWS) + instance->tls_win_certstore_name = NULL; + instance->tls_win_use_enterprise_certstore = FLB_FALSE; +# endif #endif if (plugin->flags & FLB_OUTPUT_NET) { @@ -975,6 +994,15 @@ int flb_output_set_property(struct flb_output_instance *ins, else if (prop_key_check("tls.ciphers", k, len) == 0) { flb_utils_set_plugin_string_property("tls.ciphers", &ins->tls_ciphers, tmp); } +# if defined(FLB_SYSTEM_WINDOWS) + else if (prop_key_check("tls.windows.certstore_name", k, len) == 0 && tmp) { + flb_utils_set_plugin_string_property("tls.windows.certstore_name", &ins->tls_win_certstore_name, tmp); + } + else if (prop_key_check("tls.windows.use_enterprise_store", k, len) == 0 && tmp) { + ins->tls_win_use_enterprise_certstore = flb_utils_bool(tmp); + flb_sds_destroy(tmp); + } +# endif #endif else if (prop_key_check("storage.total_limit_size", k, len) == 0 && tmp) { if (strcasecmp(tmp, "off") == 0 || @@ -1359,6 +1387,40 @@ int flb_output_init_all(struct flb_config *config) return -1; } } + +# if defined (FLB_SYSTEM_WINDOWS) + if (ins->tls_win_use_enterprise_certstore) { + ret = flb_tls_set_use_enterprise_store(ins->tls, ins->tls_win_use_enterprise_certstore); + if (ret == -1) { + flb_error("[input %s] error set up to use enterprise certstore in TLS context", + ins->name); + + return -1; + } + } + + if (ins->tls_win_certstore_name) { + flb_debug("[output %s] starting to load %s certstore in TLS context", + ins->name, ins->tls_win_certstore_name); + ret = flb_tls_set_certstore_name(ins->tls, ins->tls_win_certstore_name); + if (ret == -1) { + flb_error("[output %s] error specify certstore name in TLS context", + ins->name); + + return -1; + } + + flb_debug("[output %s] attempting to load %s certstore in TLS context", + ins->name, ins->tls_win_certstore_name); + ret = flb_tls_load_system_certificates(ins->tls); + if (ret == -1) { + flb_error("[output %s] error set up to load certstore with a user-defined name in TLS context", + ins->name); + + return -1; + } + } +# endif } #endif /* diff --git a/src/tls/flb_tls.c b/src/tls/flb_tls.c index 9015e0dd343..f0e42c265cf 100644 --- a/src/tls/flb_tls.c +++ b/src/tls/flb_tls.c @@ -216,6 +216,10 @@ struct flb_tls *flb_tls_create(int mode, tls->debug = debug; tls->mode = mode; tls->verify_hostname = FLB_FALSE; +#if defined(FLB_SYSTEM_WINDOWS) + tls->certstore_name = NULL; + tls->use_enterprise_store = FLB_FALSE; +#endif if (vhost != NULL) { tls->vhost = flb_strdup(vhost); @@ -261,6 +265,12 @@ int flb_tls_destroy(struct flb_tls *tls) flb_free(tls->vhost); } +#if defined(FLB_SYSTEM_WINDOWS) + if (tls->certstore_name) { + flb_free(tls->certstore_name); + } +#endif + flb_free(tls); return 0; @@ -286,6 +296,26 @@ int flb_tls_set_verify_hostname(struct flb_tls *tls, int verify_hostname) return 0; } +#if defined(FLB_SYSTEM_WINDOWS) +int flb_tls_set_certstore_name(struct flb_tls *tls, const char *certstore_name) +{ + if (tls) { + return tls->api->set_certstore_name(tls, certstore_name); + } + + return 0; +} + +int flb_tls_set_use_enterprise_store(struct flb_tls *tls, int use_enterprise) +{ + if (tls) { + return tls->api->set_use_enterprise_store(tls, use_enterprise); + } + + return 0; +} +#endif + int flb_tls_net_read(struct flb_tls_session *session, void *buf, size_t len) { time_t timeout_timestamp; diff --git a/src/tls/openssl.c b/src/tls/openssl.c index ad66b71bfcb..1d95293498f 100644 --- a/src/tls/openssl.c +++ b/src/tls/openssl.c @@ -56,6 +56,10 @@ struct tls_context { SSL_CTX *ctx; int mode; char *alpn; +#if defined(FLB_SYSTEM_WINDOWS) + char *certstore_name; + int use_enterprise_store; +#endif pthread_mutex_t mutex; }; @@ -148,6 +152,14 @@ static void tls_context_destroy(void *ctx_backend) ctx->alpn = NULL; } +#if defined(FLB_SYSTEM_WINDOWS) + if (ctx->certstore_name != NULL) { + flb_free(ctx->certstore_name); + + ctx->certstore_name = NULL; + } +#endif + pthread_mutex_unlock(&ctx->mutex); flb_free(ctx); @@ -291,6 +303,7 @@ static int windows_load_system_certificates(struct tls_context *ctx) const unsigned char *win_cert_data; X509_STORE *ossl_store = SSL_CTX_get_cert_store(ctx->ctx); X509 *ossl_cert; + char *certstore_name = "Root"; /* Check if OpenSSL certificate store is available */ if (!ossl_store) { @@ -298,8 +311,23 @@ static int windows_load_system_certificates(struct tls_context *ctx) return -1; } - /* Open the Windows system certificate store */ - win_store = CertOpenSystemStoreA(0, "Root"); + if (ctx->certstore_name) { + certstore_name = ctx->certstore_name; + } + + if (ctx->use_enterprise_store) { + /* Open the Windows system enterprise certificate store */ + win_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, + 0, + 0, + CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, + certstore_name); + } + else { + /* Open the Windows system certificate store */ + win_store = CertOpenSystemStoreA(0, certstore_name); + } + if (win_store == NULL) { flb_error("[tls] cannot open windows certificate store: %lu", GetLastError()); return -1; @@ -352,7 +380,8 @@ static int windows_load_system_certificates(struct tls_context *ctx) return -1; } - flb_debug("[tls] successfully loaded certificates from windows system store."); + flb_debug("[tls] successfully loaded certificates from windows system %s store.", + certstore_name); return 0; } #endif @@ -767,6 +796,34 @@ static int tls_set_ciphers(struct flb_tls *tls, const char *ciphers) return 0; } +#if defined(FLB_SYSTEM_WINDOWS) +static int tls_set_certstore_name(struct flb_tls *tls, const char *certstore_name) +{ + struct tls_context *ctx = tls->ctx; + + pthread_mutex_lock(&ctx->mutex); + + ctx->certstore_name = flb_strdup(certstore_name); + + pthread_mutex_unlock(&ctx->mutex); + + return 0; +} + +static int tls_set_use_enterprise_store(struct flb_tls *tls, int use_enterprise) +{ + struct tls_context *ctx = tls->ctx; + + pthread_mutex_lock(&ctx->mutex); + + ctx->use_enterprise_store = !!use_enterprise; + + pthread_mutex_unlock(&ctx->mutex); + + return 0; +} +#endif + static void *tls_session_create(struct flb_tls *tls, int fd) { @@ -1166,4 +1223,8 @@ static struct flb_tls_backend tls_openssl = { .net_read = tls_net_read, .net_write = tls_net_write, .net_handshake = tls_net_handshake, +#if defined(FLB_SYSTEM_WINDOWS) + .set_certstore_name = tls_set_certstore_name, + .set_use_enterprise_store = tls_set_use_enterprise_store, +#endif };