mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-04 00:38:02 +00:00
MEDIUM: ssl/cli: handle crt-store keywords in crt-list over the CLI
This patch adds crt-store keywords from the crt-list on the CLI. - keywords from crt-store can be used over the CLI when inserting certificate in a crt-list - keywords from crt-store are dumped when showing a crt-list content over the CLI The ckch_conf_kws.func function pointer needed a new "cli" parameter, in order to differenciate loading that come from the CLI or from the startup, as they don't behave the same. For example it must not try to load a file on the filesystem when loading a crt-list line from the CLI. dump_crtlist_sslconf() was renamed in dump_crtlist_conf() and takes a new ckch_conf parameter in order to dump relevant crt-store keywords.
This commit is contained in:
parent
2bcf38c7c8
commit
1bc6e990f2
@ -180,7 +180,7 @@ struct ckch_conf_kws {
|
||||
const char *name;
|
||||
ssize_t offset;
|
||||
enum parse_type_t type;
|
||||
int (*func)(void *value, char *buf, struct ckch_data *d, char **err);
|
||||
int (*func)(void *value, char *buf, struct ckch_data *d, int cli, char **err);
|
||||
char **base; /* ptr to the base path */
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ struct ckch_store *ckchs_dup(const struct ckch_store *src);
|
||||
struct ckch_store *ckch_store_new(const char *filename);
|
||||
void ckch_store_free(struct ckch_store *store);
|
||||
void ckch_store_replace(struct ckch_store *old_ckchs, struct ckch_store *new_ckchs);
|
||||
int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err);
|
||||
int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, int cli, char **err);
|
||||
|
||||
/* ckch_conf functions */
|
||||
|
||||
@ -80,11 +80,11 @@ extern struct cert_exts cert_exts[];
|
||||
extern int (*ssl_commit_crlfile_cb)(const char *path, X509_STORE *ctx, char **err);
|
||||
|
||||
/* ckch_conf keyword loading */
|
||||
static inline int ckch_conf_load_pem(void *value, char *buf, struct ckch_data *d, char **err) { return ssl_sock_load_pem_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_key(void *value, char *buf, struct ckch_data *d, char **err) { return ssl_sock_load_key_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_ocsp_response(void *value, char *buf, struct ckch_data *d, char **err) { return ssl_sock_load_ocsp_response_from_file(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_ocsp_issuer(void *value, char *buf, struct ckch_data *d, char **err) { return ssl_sock_load_issuer_file_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_sctl(void *value, char *buf, struct ckch_data *d, char **err) { return ssl_sock_load_sctl_from_file(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_pem(void *value, char *buf, struct ckch_data *d, int cli, char **err) { if (cli) return 0; return ssl_sock_load_pem_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_key(void *value, char *buf, struct ckch_data *d, int cli, char **err) { if (cli) return 0; return ssl_sock_load_key_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_ocsp_response(void *value, char *buf, struct ckch_data *d, int cli, char **err) { if (cli) return 0; return ssl_sock_load_ocsp_response_from_file(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_ocsp_issuer(void *value, char *buf, struct ckch_data *d, int cli, char **err) { if (cli) return 0; return ssl_sock_load_issuer_file_into_ckch(value, buf, d, err); }
|
||||
static inline int ckch_conf_load_sctl(void *value, char *buf, struct ckch_data *d, int cli, char **err) { if (cli) return 0; return ssl_sock_load_sctl_from_file(value, buf, d, err); }
|
||||
|
||||
#endif /* USE_OPENSSL */
|
||||
#endif /* _HAPROXY_SSL_CRTLIST_H */
|
||||
|
@ -55,7 +55,7 @@ void ssl_destroy_ocsp_update_task(void);
|
||||
|
||||
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp);
|
||||
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, char **err);
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, char **err);
|
||||
|
||||
#endif /* (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) */
|
||||
|
||||
|
@ -962,6 +962,9 @@ struct ckch_store *ckchs_dup(const struct ckch_store *src)
|
||||
if (!ssl_sock_copy_cert_key_and_chain(src->data, dst->data))
|
||||
goto error;
|
||||
|
||||
|
||||
dst->conf.ocsp_update_mode = src->conf.ocsp_update_mode;
|
||||
|
||||
return dst;
|
||||
|
||||
error:
|
||||
@ -1026,7 +1029,7 @@ struct ckch_store *ckch_store_new_load_files_conf(char *name, struct ckch_conf *
|
||||
goto end;
|
||||
}
|
||||
|
||||
cfgerr = ckch_store_load_files(conf, ckchs, err);
|
||||
cfgerr = ckch_store_load_files(conf, ckchs, 0, err);
|
||||
if (cfgerr & ERR_FATAL)
|
||||
goto end;
|
||||
|
||||
@ -4033,19 +4036,13 @@ struct ckch_conf_kws ckch_conf_kws[] = {
|
||||
};
|
||||
|
||||
/* crt-store does not try to find files, but use the stored filename */
|
||||
int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err)
|
||||
int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, int cli, char **err)
|
||||
{
|
||||
int i;
|
||||
int err_code = 0;
|
||||
int rc = 1;
|
||||
struct ckch_data *d = c->data;
|
||||
|
||||
/* crt */
|
||||
if (!f->crt) {
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; ckch_conf_kws[i].name; i++) {
|
||||
void *src = NULL;
|
||||
|
||||
@ -4079,7 +4076,7 @@ int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err)
|
||||
}
|
||||
path = path_base;
|
||||
}
|
||||
rc = ckch_conf_kws[i].func(path, NULL, d, err);
|
||||
rc = ckch_conf_kws[i].func(path, NULL, d, cli, err);
|
||||
if (rc) {
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
memprintf(err, "%s '%s' cannot be read or parsed.", err && *err ? *err : "", path);
|
||||
@ -4092,7 +4089,7 @@ int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err)
|
||||
case PARSE_TYPE_ONOFF:
|
||||
{
|
||||
int v = *(int *)src;
|
||||
rc = ckch_conf_kws[i].func(&v, NULL, d, err);
|
||||
rc = ckch_conf_kws[i].func(&v, NULL, d, cli, err);
|
||||
if (rc) {
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
memprintf(err, "%s '%d' cannot be read or parsed.", err && *err ? *err : "", v);
|
||||
@ -4313,7 +4310,7 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
|
||||
if (!c)
|
||||
goto alloc_error;
|
||||
|
||||
err_code |= ckch_store_load_files(&f, c, err);
|
||||
err_code |= ckch_store_load_files(&f, c, 0, err);
|
||||
if (err_code & ERR_FATAL)
|
||||
goto out;
|
||||
|
||||
|
@ -825,14 +825,21 @@ end:
|
||||
* Take an ssl_bind_conf structure and append the configuration line used to
|
||||
* create it in the buffer
|
||||
*/
|
||||
static void dump_crtlist_sslconf(struct buffer *buf, const struct ssl_bind_conf *conf)
|
||||
static void dump_crtlist_conf(struct buffer *buf, const struct ssl_bind_conf *conf, const struct ckch_conf *cc)
|
||||
{
|
||||
int space = 0;
|
||||
|
||||
if (conf == NULL)
|
||||
if (conf == NULL && cc->used == 0)
|
||||
return;
|
||||
|
||||
chunk_appendf(buf, " [");
|
||||
|
||||
|
||||
if (conf == NULL)
|
||||
goto dump_ckch;
|
||||
|
||||
/* first dump all ssl_conf keywords */
|
||||
|
||||
#ifdef OPENSSL_NPN_NEGOTIATED
|
||||
if (conf->npn_str) {
|
||||
int len = conf->npn_len;
|
||||
@ -958,7 +965,22 @@ static void dump_crtlist_sslconf(struct buffer *buf, const struct ssl_bind_conf
|
||||
space++;
|
||||
}
|
||||
|
||||
/* FIXME: dump crt-store keywords */
|
||||
/* then dump the ckch_conf */
|
||||
dump_ckch:
|
||||
if (!cc->used)
|
||||
goto end;
|
||||
|
||||
if (cc->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_OFF) {
|
||||
if (space) chunk_appendf(buf, " ");
|
||||
chunk_appendf(buf, "ocsp-update off");
|
||||
space++;
|
||||
} else if (cc->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) {
|
||||
if (space) chunk_appendf(buf, " ");
|
||||
chunk_appendf(buf, "ocsp-update on");
|
||||
space++;
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
chunk_appendf(buf, "]");
|
||||
|
||||
@ -1042,7 +1064,7 @@ static int cli_io_handler_dump_crtlist_entries(struct appctx *appctx)
|
||||
chunk_appendf(trash, "%s", filename);
|
||||
if (ctx->mode == 's') /* show */
|
||||
chunk_appendf(trash, ":%d", entry->linenum);
|
||||
dump_crtlist_sslconf(trash, entry->ssl_conf);
|
||||
dump_crtlist_conf(trash, entry->ssl_conf, &store->conf);
|
||||
dump_crtlist_filters(trash, entry);
|
||||
chunk_appendf(trash, "\n");
|
||||
|
||||
@ -1272,6 +1294,7 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
struct ebpt_node *inserted;
|
||||
struct crtlist *crtlist;
|
||||
struct crtlist_entry *entry = NULL;
|
||||
struct ckch_conf cc = {};
|
||||
char *end;
|
||||
|
||||
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
|
||||
@ -1302,6 +1325,7 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
if (payload) {
|
||||
char *lf;
|
||||
|
||||
@ -1311,8 +1335,7 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
goto error;
|
||||
}
|
||||
/* cert_path is filled here */
|
||||
cfgerr |= crtlist_parse_line(payload, &cert_path, entry, NULL, "CLI", 1, 1, &err);
|
||||
/* FIXME: handle the ckch_conf */
|
||||
cfgerr |= crtlist_parse_line(payload, &cert_path, entry, &cc, "CLI", 1, 1, &err);
|
||||
if (cfgerr & ERR_CODE)
|
||||
goto error;
|
||||
} else {
|
||||
@ -1363,6 +1386,24 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* We can use a crt-store keyword when:
|
||||
* - no ckch_inst are linked OR
|
||||
* - ckch_inst are linked but exact same ckch_conf is used.
|
||||
*/
|
||||
if (LIST_ISEMPTY(&store->ckch_inst)) {
|
||||
|
||||
store->conf = cc;
|
||||
/* fresh new, run more init (for example init ocsp-update tasks) */
|
||||
cfgerr |= ckch_store_load_files(&cc, store, 1, &err);
|
||||
if (cfgerr & ERR_FATAL)
|
||||
goto error;
|
||||
|
||||
} else if (ckch_conf_cmp(&store->conf, &cc, &err) != 0) {
|
||||
memprintf(&err, "'%s' is already instantiated with incompatible parameters:\n %s", cert_path, err ? err : "");
|
||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* check if it's possible to insert this new crtlist_entry */
|
||||
entry->node.key = store;
|
||||
inserted = ebpt_insert(&crtlist->entries, &entry->node);
|
||||
@ -1372,8 +1413,8 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
}
|
||||
|
||||
/* this is supposed to be a directory (EB_ROOT_UNIQUE), so no ssl_conf are allowed */
|
||||
if ((entry->ssl_conf || entry->filters) && eb_gettag(crtlist->entries.b[EB_RGHT])) {
|
||||
memprintf(&err, "this is a directory, SSL configuration and filters are not allowed");
|
||||
if ((entry->ssl_conf || entry->filters || cc.used) && eb_gettag(crtlist->entries.b[EB_RGHT])) {
|
||||
memprintf(&err, "this is a directory, SSL configuration, crt-store keywords and filters are not allowed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1389,6 +1430,7 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
|
||||
return 0;
|
||||
|
||||
error:
|
||||
ckch_conf_clean(&cc);
|
||||
crtlist_entry_free(entry);
|
||||
HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock);
|
||||
err = memprintf(&err, "Can't edit the crt-list: %s\n", err ? err : "");
|
||||
|
@ -1986,7 +1986,7 @@ static int ocsp_update_parse_global_http_proxy(char **args, int section_type, st
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, char **err)
|
||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, char **err)
|
||||
{
|
||||
int ocsp_update_mode = *(int *)value;
|
||||
int ret = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user