- if (depth == 0 && conf->check_cert_cn != NULL) {
- if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, handler->request, NULL)) {
- radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
- conf->check_cert_cn);
- /* if this fails, fail the verification */
- my_ok = 0;
- }
- DEBUG2(" rlm_eap_tls: checking certificate CN (%s) with xlat'ed value (%s)", buf, cn_str);
- if (strncmp(cn_str, buf, sizeof(buf)) != 0) {
- my_ok = 0;
- radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", buf, cn_str);
+ if (depth == 0) {
+ /*
+ * If the conf tells us to, check cert issuer
+ * against the specified value and fail
+ * verification if they don't match.
+ */
+ if (conf->check_cert_issuer &&
+ (strcmp(issuer, conf->check_cert_issuer) != 0)) {
+ radlog(L_AUTH, "rlm_eap_tls: Certificate issuer (%s) does not match specified value (%s)!", issuer, conf->check_cert_issuer);
+ my_ok = 0;
+ }
+
+ /*
+ * If the conf tells us to, check the CN in the
+ * cert against xlat'ed value, but only if the
+ * previous checks passed.
+ */
+ if (my_ok && conf->check_cert_cn) {
+ if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, handler->request, NULL)) {
+ radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
+ conf->check_cert_cn);
+ /* if this fails, fail the verification */
+ my_ok = 0;
+ } else {
+ RDEBUG2("checking certificate CN (%s) with xlat'ed value (%s)", common_name, cn_str);
+ if (strcmp(cn_str, common_name) != 0) {
+ radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", common_name, cn_str);
+ my_ok = 0;
+ }
+ }
+ } /* check_cert_cn */
+
+ while (conf->verify_client_cert_cmd) {
+ char filename[256];
+ FILE *fp;
+
+ snprintf(filename, sizeof(filename), "%s/%s.client.XXXXXXXX",
+ conf->verify_tmp_dir, progname);
+ if (mkstemp(filename) < 0) {
+ RDEBUG("Failed creating file in %s: %s",
+ conf->verify_tmp_dir, strerror(errno));
+ break;
+ }
+
+ fp = fopen(filename, "w");
+ if (!fp) {
+ RDEBUG("Failed opening file %s: %s",
+ filename, strerror(errno));
+ break;
+ }
+
+ if (!PEM_write_X509(fp, client_cert)) {
+ fclose(fp);
+ RDEBUG("Failed writing certificate to file");
+ goto do_unlink;
+ }
+ fclose(fp);
+
+ if (!radius_pairmake(request, &request->packet->vps,
+ "TLS-Client-Cert-Filename",
+ filename, T_OP_SET)) {
+ RDEBUG("Failed creating TLS-Client-Cert-Filename");
+
+ goto do_unlink;
+ }
+
+ RDEBUG("Verifying client certificate: %s",
+ conf->verify_client_cert_cmd);
+ if (radius_exec_program(conf->verify_client_cert_cmd,
+ request, 1, NULL, 0,
+ request->packet->vps,
+ NULL, 1) != 0) {
+ radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) fails external verification!", common_name);
+ my_ok = 0;
+ } else {
+ RDEBUG("Client certificate CN %s passed external validation", common_name);
+ }
+
+ do_unlink:
+ unlink(filename);
+ break;