File sendmail-8.14.3-tls-null-char-cert.dif of Package sendmail
--- cf/README
+++ cf/README 2010-01-19 12:47:11.045921000 +0100
@@ -3142,7 +3142,7 @@
extensions are:
CN:name name must match ${cn_subject}
-CN ${server_name} must match ${cn_subject}
+CN ${client_name}/${server_name} must match ${cn_subject}
CS:name name must match ${cert_subject}
CI:name name must match ${cert_issuer}
--- doc/op/op.me
+++ doc/op/op.me 2010-01-19 12:47:11.062934000 +0100
@@ -4952,9 +4952,21 @@
.ip ${cn_issuer}
The CN (common name) of the CA that signed the presented certificate
(STARTTLS only).
+Note: if the CN cannot be extracted properly it will be replaced by
+one of these strings based on the encountered error:
+.(b
+.ta 25n
+BadCertificateContainsNUL CN contains a NUL character
+BadCertificateTooLong CN is too long
+BadCertificateUnknown CN could not be extracted
+.)b
+In the last case, some other (unspecific) error occurred.
.ip ${cn_subject}
The CN (common name) of the presented certificate
(STARTTLS only).
+See
+.b ${cn_issuer}
+for possible replacements.
.ip ${currHeader}
Header value as quoted string
(possibly truncated to
--- sendmail/tls.c
+++ sendmail/tls.c 2010-01-19 12:47:11.069921000 +0100
@@ -1196,23 +1196,62 @@
if (cert != NULL)
{
unsigned int n;
+ X509_NAME *subj, *issuer;
unsigned char md[EVP_MAX_MD_SIZE];
char buf[MAXNAME];
- X509_NAME_oneline(X509_get_subject_name(cert),
- buf, sizeof(buf));
+ subj = X509_get_subject_name(cert);
+ issuer = X509_get_issuer_name(cert);
+ X509_NAME_oneline(subj, buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cert_subject}"),
xtextify(buf, "<>\")"));
- X509_NAME_oneline(X509_get_issuer_name(cert),
- buf, sizeof(buf));
+ X509_NAME_oneline(issuer, buf, sizeof(buf));
macdefine(mac, A_TEMP, macid("{cert_issuer}"),
xtextify(buf, "<>\")"));
- X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
- NID_commonName, buf, sizeof(buf));
+
+#define CHECK_X509_NAME(which) \
+ do { \
+ if (r == -1) \
+ { \
+ sm_strlcpy(buf, "BadCertificateUnknown", sizeof(buf)); \
+ if (LogLevel > 7) \
+ sm_syslog(LOG_INFO, NOQID, \
+ "STARTTLS=%s, relay=%.100s, field=%s, status=failed to extract CN", \
+ who, \
+ host == NULL ? "local" : host, \
+ which); \
+ } \
+ else if ((size_t)r >= sizeof(buf) - 1) \
+ { \
+ sm_strlcpy(buf, "BadCertificateTooLong", sizeof(buf)); \
+ if (LogLevel > 7) \
+ sm_syslog(LOG_INFO, NOQID, \
+ "STARTTLS=%s, relay=%.100s, field=%s, status=CN too long", \
+ who, \
+ host == NULL ? "local" : host, \
+ which); \
+ } \
+ else if ((size_t)r > strlen(buf)) \
+ { \
+ sm_strlcpy(buf, "BadCertificateContainsNUL", \
+ sizeof(buf)); \
+ if (LogLevel > 7) \
+ sm_syslog(LOG_INFO, NOQID, \
+ "STARTTLS=%s, relay=%.100s, field=%s, status=CN contains NUL", \
+ who, \
+ host == NULL ? "local" : host, \
+ which); \
+ } \
+ } while (0)
+
+ r = X509_NAME_get_text_by_NID(subj, NID_commonName, buf,
+ sizeof buf);
+ CHECK_X509_NAME("cn_subject");
macdefine(mac, A_TEMP, macid("{cn_subject}"),
xtextify(buf, "<>\")"));
- X509_NAME_get_text_by_NID(X509_get_issuer_name(cert),
- NID_commonName, buf, sizeof(buf));
+ r = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf,
+ sizeof buf);
+ CHECK_X509_NAME("cn_issuer");
macdefine(mac, A_TEMP, macid("{cn_issuer}"),
xtextify(buf, "<>\")"));
n = 0;