session server tls BUGFIX check all matching CTNs
diff --git a/src/session_server_tls.c b/src/session_server_tls.c
index 040836f..9b9b3f1 100644
--- a/src/session_server_tls.c
+++ b/src/session_server_tls.c
@@ -215,7 +215,7 @@
*username = strdup(common_name);
if (!*username) {
ERRMEM;
- return 1;
+ return -1;
}
free(subject);
} else {
@@ -240,7 +240,7 @@
#endif
if (!*username) {
ERRMEM;
- return 1;
+ return -1;
}
break;
}
@@ -255,7 +255,7 @@
#endif
if (!*username) {
ERRMEM;
- return 1;
+ return -1;
}
break;
}
@@ -314,7 +314,7 @@
/* return: 0 - OK, 1 - no match, -1 - error */
static int
-nc_tls_cert_to_name(struct nc_ctn *ctn_first, X509 *cert, NC_TLS_CTN_MAPTYPE *map_type, const char **name)
+nc_tls_cert_to_name(struct nc_session *session, struct nc_ctn *ctn_first, X509 *cert)
{
char *digest_md5 = NULL, *digest_sha1 = NULL, *digest_sha224 = NULL;
char *digest_sha256 = NULL, *digest_sha384 = NULL, *digest_sha512 = NULL;
@@ -322,18 +322,23 @@
unsigned int buf_len = 64;
int ret = 0;
struct nc_ctn *ctn;
+ NC_TLS_CTN_MAPTYPE map_type;
+ char *username = NULL;
if (!buf) {
ERRMEM;
return -1;
}
- if (!ctn_first || !cert || !map_type || !name) {
+ if (!session || !ctn_first || !cert) {
free(buf);
return -1;
}
for (ctn = ctn_first; ctn; ctn = ctn->next) {
+ /* reset map_type */
+ map_type = NC_TLS_CTN_UNKNOWN;
+
/* first make sure the entry is valid */
if (!ctn->fingerprint || !ctn->map_type || ((ctn->map_type == NC_TLS_CTN_SPECIFIED) && !ctn->name)) {
VRB(NULL, "Cert verify CTN: entry with id %u not valid, skipping.", ctn->id);
@@ -352,13 +357,9 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_md5)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* SHA-1 */
@@ -373,13 +374,9 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_sha1)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* SHA-224 */
@@ -394,13 +391,9 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_sha224)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* SHA-256 */
@@ -415,13 +408,9 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_sha256)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* SHA-384 */
@@ -436,13 +425,9 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_sha384)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* SHA-512 */
@@ -457,18 +442,45 @@
}
if (!strcasecmp(ctn->fingerprint + 3, digest_sha512)) {
- /* we got ourselves a winner! */
+ /* we got ourselves a potential winner! */
VRB(NULL, "Cert verify CTN: entry with a matching fingerprint found.");
- *map_type = ctn->map_type;
- if (ctn->map_type == NC_TLS_CTN_SPECIFIED) {
- *name = ctn->name;
- }
- break;
+ map_type = ctn->map_type;
}
/* unknown */
} else {
WRN(NULL, "Unknown fingerprint algorithm used (%s), skipping.", ctn->fingerprint);
+ continue;
+ }
+
+ if (map_type != NC_TLS_CTN_UNKNOWN) {
+ /* found a fingerprint match */
+ if (map_type == NC_TLS_CTN_SPECIFIED) {
+ /* specified -> get username from the ctn entry */
+ session->username = strdup(ctn->name);
+ if (!session->username) {
+ ERRMEM;
+ ret = -1;
+ goto cleanup;
+ }
+ } else {
+ /* try to get the username from the cert with this ctn's map type */
+ ret = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &username);
+ if (ret == -1) {
+ /* fatal error */
+ goto cleanup;
+ } else if (ret) {
+ /* didn't get username, try next ctn entry */
+ continue;
+ }
+
+ /* success */
+ session->username = username;
+ }
+
+ /* matching fingerprint found and username obtained, success */
+ ret = 0;
+ goto cleanup;
}
}
@@ -507,8 +519,6 @@
const ASN1_INTEGER *serial;
int i, n, rc, depth;
char *cp;
- const char *username = NULL;
- NC_TLS_CTN_MAPTYPE map_type = 0;
const ASN1_TIME *last_update = NULL, *next_update = NULL;
/* get the thread session */
@@ -655,8 +665,7 @@
}
/* cert-to-name */
- rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);
-
+ rc = nc_tls_cert_to_name(session, opts->ctn, cert);
if (rc) {
if (rc == -1) {
/* fatal error */
@@ -666,20 +675,6 @@
goto fail;
}
- /* cert-to-name match, now to extract the specific field from the peer cert */
- if (map_type == NC_TLS_CTN_SPECIFIED) {
- session->username = strdup(username);
- } else {
- rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
- if (rc) {
- if (rc == -1) {
- depth = 0;
- }
- goto fail;
- }
- session->username = cp;
- }
-
VRB(NULL, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {
@@ -721,8 +716,6 @@
long serial;
int i, n, rc, depth;
char *cp;
- const char *username = NULL;
- NC_TLS_CTN_MAPTYPE map_type = 0;
ASN1_TIME *last_update = NULL, *next_update = NULL;
/* get the thread session */
@@ -869,8 +862,7 @@
}
/* cert-to-name */
- rc = nc_tls_cert_to_name(opts->ctn, cert, &map_type, &username);
-
+ rc = nc_tls_cert_to_name(session, opts->ctn, cert);
if (rc) {
if (rc == -1) {
/* fatal error */
@@ -880,20 +872,6 @@
goto fail;
}
- /* cert-to-name match, now to extract the specific field from the peer cert */
- if (map_type == NC_TLS_CTN_SPECIFIED) {
- session->username = strdup(username);
- } else {
- rc = nc_tls_ctn_get_username_from_cert(session->opts.server.client_cert, map_type, &cp);
- if (rc) {
- if (rc == -1) {
- depth = 0;
- }
- goto fail;
- }
- session->username = cp;
- }
-
VRB(session, "Cert verify CTN: new client username recognized as \"%s\".", session->username);
if (server_opts.user_verify_clb && !server_opts.user_verify_clb(session)) {