Skip to content

Commit f1d2a54

Browse files
romanmichalvasko
authored andcommitted
server config BUGFIX handle delete on client-auth
1 parent 43cc616 commit f1d2a54

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

src/server_config.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,11 +763,16 @@ nc_server_config_del_certs(struct nc_cert_grouping *certs_grp)
763763
free(certs_grp->certs[i].name);
764764
free(certs_grp->certs[i].data);
765765
}
766+
certs_grp->cert_count = 0;
766767
free(certs_grp->certs);
767768
certs_grp->certs = NULL;
768769
} else if (certs_grp->store == NC_STORE_TRUSTSTORE) {
769770
free(certs_grp->ts_ref);
771+
certs_grp->ts_ref = NULL;
770772
}
773+
774+
/* reset to the default */
775+
certs_grp->store = NC_STORE_LOCAL;
771776
}
772777

773778
static void
@@ -2965,6 +2970,115 @@ nc_server_config_asymmetric_key(const struct lyd_node *node, NC_OPERATION op)
29652970
return ret;
29662971
}
29672972

2973+
static int
2974+
nc_server_config_client_authentication(const struct lyd_node *node, NC_OPERATION op)
2975+
{
2976+
int ret = 0;
2977+
struct nc_server_tls_opts *opts;
2978+
struct nc_ch_client *ch_client = NULL;
2979+
2980+
assert(!strcmp(LYD_NAME(node), "client-authentication"));
2981+
2982+
/* only do something on delete and if we're in the TLS subtree,
2983+
* because this is a presence container unlike its SSH counterpart */
2984+
if (!is_tls(node) || (op != NC_OP_DELETE)) {
2985+
return 0;
2986+
}
2987+
2988+
/* LOCK */
2989+
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
2990+
/* to avoid unlock on fail */
2991+
return 1;
2992+
}
2993+
2994+
if (nc_server_config_get_tls_opts(node, ch_client, &opts)) {
2995+
ret = 1;
2996+
goto cleanup;
2997+
}
2998+
2999+
nc_server_config_del_certs(&opts->ca_certs);
3000+
nc_server_config_del_certs(&opts->ee_certs);
3001+
3002+
cleanup:
3003+
if (is_ch(node)) {
3004+
/* UNLOCK */
3005+
nc_ch_client_unlock(ch_client);
3006+
}
3007+
return ret;
3008+
}
3009+
3010+
static int
3011+
nc_server_config_ca_certs(const struct lyd_node *node, NC_OPERATION op)
3012+
{
3013+
int ret = 0;
3014+
struct nc_server_tls_opts *opts;
3015+
struct nc_ch_client *ch_client = NULL;
3016+
3017+
assert(!strcmp(LYD_NAME(node), "ca-certs"));
3018+
3019+
/* only do something on delete and if we're in the TLS subtree,
3020+
* because SSH certs are not yet supported */
3021+
if (!is_tls(node) || (op != NC_OP_DELETE)) {
3022+
return 0;
3023+
}
3024+
3025+
/* LOCK */
3026+
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
3027+
/* to avoid unlock on fail */
3028+
return 1;
3029+
}
3030+
3031+
if (nc_server_config_get_tls_opts(node, ch_client, &opts)) {
3032+
ret = 1;
3033+
goto cleanup;
3034+
}
3035+
3036+
nc_server_config_del_certs(&opts->ca_certs);
3037+
3038+
cleanup:
3039+
if (is_ch(node)) {
3040+
/* UNLOCK */
3041+
nc_ch_client_unlock(ch_client);
3042+
}
3043+
return ret;
3044+
}
3045+
3046+
static int
3047+
nc_server_config_ee_certs(const struct lyd_node *node, NC_OPERATION op)
3048+
{
3049+
int ret = 0;
3050+
struct nc_server_tls_opts *opts;
3051+
struct nc_ch_client *ch_client = NULL;
3052+
3053+
assert(!strcmp(LYD_NAME(node), "ee-certs"));
3054+
3055+
/* only do something on delete and if we're in the TLS subtree,
3056+
* because SSH certs are not yet supported */
3057+
if (!is_tls(node) || (op != NC_OP_DELETE)) {
3058+
return 0;
3059+
}
3060+
3061+
/* LOCK */
3062+
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
3063+
/* to avoid unlock on fail */
3064+
return 1;
3065+
}
3066+
3067+
if (nc_server_config_get_tls_opts(node, ch_client, &opts)) {
3068+
ret = 1;
3069+
goto cleanup;
3070+
}
3071+
3072+
nc_server_config_del_certs(&opts->ee_certs);
3073+
3074+
cleanup:
3075+
if (is_ch(node)) {
3076+
/* UNLOCK */
3077+
nc_ch_client_unlock(ch_client);
3078+
}
3079+
return ret;
3080+
}
3081+
29683082
static int
29693083
nc_server_config_create_ca_certs_certificate(const struct lyd_node *node, struct nc_server_tls_opts *opts)
29703084
{
@@ -3795,6 +3909,12 @@ nc_server_config_parse_netconf_server(const struct lyd_node *node, NC_OPERATION
37953909
ret = nc_server_config_cert_data(node, op);
37963910
} else if (!strcmp(name, "asymmetric-key")) {
37973911
ret = nc_server_config_asymmetric_key(node, op);
3912+
} else if (!strcmp(name, "client-authentication")) {
3913+
ret = nc_server_config_client_authentication(node, op);
3914+
} else if (!strcmp(name, "ca-certs")) {
3915+
ret = nc_server_config_ca_certs(node, op);
3916+
} else if (!strcmp(name, "ee-certs")) {
3917+
ret = nc_server_config_ee_certs(node, op);
37983918
} else if (!strcmp(name, "certificate")) {
37993919
ret = nc_server_config_certificate(node, op);
38003920
} else if (!strcmp(name, "cert-to-name")) {

src/session_server_tls.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,30 @@ nc_server_tls_accept_check(int accept_ret, void *tls_session)
766766
return accept_ret;
767767
}
768768

769+
/**
770+
* @brief Get the number of certificates in a certificate grouping.
771+
*
772+
* @param[in] certs_grp Certificate grouping to get the number of certificates from.
773+
* @return Number of certificates in the grouping, or -1 on error.
774+
*/
775+
static uint16_t
776+
nc_server_tls_get_num_certs(struct nc_cert_grouping *certs_grp)
777+
{
778+
uint16_t count = 0;
779+
struct nc_certificate *certs;
780+
781+
if (certs_grp->store == NC_STORE_LOCAL) {
782+
count = certs_grp->cert_count;
783+
} else if (certs_grp->store == NC_STORE_TRUSTSTORE) {
784+
if (nc_server_tls_truststore_ref_get_certs(certs_grp->ts_ref, &certs, &count)) {
785+
ERR(NULL, "Getting CA certificates from the truststore reference \"%s\" failed.", certs_grp->ts_ref);
786+
return -1;
787+
}
788+
}
789+
790+
return count;
791+
}
792+
769793
int
770794
nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opts, int sock, int timeout)
771795
{
@@ -774,6 +798,7 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt
774798
struct nc_tls_verify_cb_data cb_data = {0};
775799
struct nc_endpt *referenced_endpt;
776800
void *tls_cfg, *srv_cert, *srv_pkey, *cert_store, *crl_store;
801+
uint32_t cert_count = 0;
777802

778803
tls_cfg = srv_cert = srv_pkey = cert_store = crl_store = NULL;
779804

@@ -818,6 +843,20 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt
818843
}
819844
}
820845

846+
/* Check if there are no CA/end entity certs configured, which is a valid config.
847+
* However, that would imply not using TLS for auth, which is not (yet) supported */
848+
if (!opts->referenced_endpt_name) {
849+
cert_count = nc_server_tls_get_num_certs(&opts->ca_certs) + nc_server_tls_get_num_certs(&opts->ee_certs);
850+
} else {
851+
cert_count = nc_server_tls_get_num_certs(&opts->ca_certs) + nc_server_tls_get_num_certs(&opts->ee_certs) +
852+
nc_server_tls_get_num_certs(&referenced_endpt->opts.tls->ca_certs) +
853+
nc_server_tls_get_num_certs(&referenced_endpt->opts.tls->ee_certs);
854+
}
855+
if (cert_count <= 0) {
856+
ERR(session, "Neither CA nor end-entity certificates configured.");
857+
goto fail;
858+
}
859+
821860
if (nc_session_tls_crl_from_cert_ext_fetch(srv_cert, cert_store, &crl_store)) {
822861
ERR(session, "Loading server CRL failed.");
823862
goto fail;

0 commit comments

Comments
 (0)