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;
openSUSE Build Service is sponsored by