return NULL;
}
+
+/*
+ * Free a sni filters array generated by ckch_inst_sni_ctx_to_sni_filters()
+ */
+static inline void free_sni_filters(char **sni_filter, int fcount)
+{
+ int i;
+
+ if (sni_filter) {
+ for (i = 0; i < fcount; i++) {
+ if (sni_filter[i]) {
+ free(sni_filter[i]);
+ sni_filter[i] = NULL;
+ }
+ }
+ free(sni_filter);
+ }
+}
+
+/*
+ * Fill <*sni_filter> with an allocated array of ptr to the existing filters,
+ * The caller should free <*sni_filter>.
+ * Fill <*fcount> with the number of filters
+ * Return an ERR_* code.
+ */
+static int ckch_inst_sni_ctx_to_sni_filters(const struct ckch_inst *ckchi, char ***sni_filter, int *fcount, char **err)
+{
+ struct sni_ctx *sc0;
+ int errcode = 0;
+ int i = 0;
+ char **tmp_filter;
+ int tmp_fcount = 0;
+
+ list_for_each_entry(sc0, &ckchi->sni_ctx, by_ckch_inst) {
+ tmp_fcount++;
+ }
+
+ if (!tmp_fcount)
+ goto end;
+
+ tmp_filter = malloc(sizeof(*tmp_filter) * tmp_fcount);
+ if (!tmp_filter) {
+ errcode |= ERR_FATAL|ERR_ALERT;
+ goto error;
+ }
+
+ list_for_each_entry(sc0, &ckchi->sni_ctx, by_ckch_inst) {
+ size_t len = strlen((char *)sc0->name.key);
+
+ /* we need to alloc and copy to insert a '!' or/and a '*' */
+ tmp_filter[i] = calloc(1, len + sc0->neg + sc0->wild + 1);
+ if (!tmp_filter[i]) {
+ errcode |= ERR_FATAL|ERR_ALERT;
+ goto error;
+ }
+
+ if (sc0->neg)
+ *tmp_filter[i] = '!';
+ if (sc0->wild)
+ *(tmp_filter[i] + sc0->neg) = '*';
+
+ memcpy(tmp_filter[i] + sc0->neg + sc0->wild, (char *)sc0->name.key, len + 1);
+ i++;
+ }
+end:
+ *sni_filter = tmp_filter;
+ *fcount = tmp_fcount;
+
+ return errcode;
+error:
+ memprintf(err, "%sUnable to generate filters!",
+ err && *err ? *err : "");
+ free_sni_filters(tmp_filter, tmp_fcount);
+
+ return errcode;
+}
+
+
#if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL
/*
certs_and_keys = ckchs->ckch;
- /* at least one of the instances is using filters during the config
- * parsing, that's ok to inherit this during loading on CLI */
- ckchs->filters |= !!fcount;
-
/* Process each ckch and update keytypes for each CN/SAN
* for example, if CN/SAN www.a.com is associated with
* certs with keytype 0 and 2, then at the end of the loop,
ckch = ckchs->ckch;
- /* at least one of the instances is using filters during the config
- * parsing, that's ok to inherit this during loading on CLI */
- ckchs->filters |= !!fcount;
-
ctx = SSL_CTX_new(SSLv23_server_method());
if (!ctx) {
memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
/* walk through the old ckch_inst and creates new ckch_inst using the updated ckchs */
list_for_each_entry_from(ckchi, &old_ckchs->ckch_inst, by_ckchs) {
struct ckch_inst *new_inst;
+ char **sni_filter = NULL;
+ int fcount = 0;
/* it takes a lot of CPU to creates SSL_CTXs, so we yield every 10 CKCH instances */
if (y >= 10) {
goto yield;
}
+ errcode |= ckch_inst_sni_ctx_to_sni_filters(ckchi, &sni_filter, &fcount, &err);
+ if (errcode & ERR_CODE)
+ goto error;
+
if (new_ckchs->multi)
- errcode |= ckch_inst_new_load_multi_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, NULL, 0, &new_inst, &err);
+ errcode |= ckch_inst_new_load_multi_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, sni_filter, fcount, &new_inst, &err);
else
- errcode |= ckch_inst_new_load_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, NULL, 0, &new_inst, &err);
+ errcode |= ckch_inst_new_load_store(new_ckchs->path, new_ckchs, ckchi->bind_conf, ckchi->ssl_conf, sni_filter, fcount, &new_inst, &err);
+
+ free_sni_filters(sni_filter, fcount);
+ sni_filter = NULL;
if (errcode & ERR_CODE)
goto error;
return cli_dynerr(appctx, err);
}
-
/*
* Parsing function of `set ssl cert`, it updates or creates a temporary ckch.
*/
old_ckchs = appctx->ctx.ssl.old_ckchs;
- /* TODO: handle filters */
- if (old_ckchs->filters) {
- memprintf(&err, "%sCertificates used in crt-list with filters are not supported!\n",
- err ? err : "");
- errcode |= ERR_ALERT | ERR_FATAL;
- goto end;
- }
-
/* duplicate the ckch store */
new_ckchs = ckchs_dup(old_ckchs);
if (!new_ckchs) {