Sat Jan 23 09:08:07 2021 UTC ()
loudmouth: add upstream patch fixing an SSL problem

Requested by Adrian Immanuel Kiess in PR 55944.

New release requested upstream (https://github.com/mcabber/loudmouth/issues/42)

Bump PKGREVISION.


(wiz)
diff -r1.50 -r1.51 pkgsrc/chat/loudmouth/Makefile
diff -r1.21 -r1.22 pkgsrc/chat/loudmouth/distinfo
diff -r0 -r1.1 pkgsrc/chat/loudmouth/patches/patch-loudmouth_lm-ssl-openssl.c

cvs diff -r1.50 -r1.51 pkgsrc/chat/loudmouth/Makefile (expand / switch to unified diff)

--- pkgsrc/chat/loudmouth/Makefile 2020/05/31 15:43:17 1.50
+++ pkgsrc/chat/loudmouth/Makefile 2021/01/23 09:08:07 1.51
@@ -1,23 +1,23 @@ @@ -1,23 +1,23 @@
1# $NetBSD: Makefile,v 1.50 2020/05/31 15:43:17 rillig Exp $ 1# $NetBSD: Makefile,v 1.51 2021/01/23 09:08:07 wiz Exp $
2 2
3DISTNAME= loudmouth-1.5.3 3DISTNAME= loudmouth-1.5.3
4PKGREVISION= 2 4PKGREVISION= 3
5CATEGORIES= chat 5CATEGORIES= chat
6MASTER_SITES= https://mcabber.com/files/loudmouth/ 6MASTER_SITES= https://mcabber.com/files/loudmouth/
7EXTRACT_SUFX= .tar.bz2 7EXTRACT_SUFX= .tar.bz2
8 8
9MAINTAINER= pkgsrc-users@NetBSD.org 9MAINTAINER= pkgsrc-users@NetBSD.org
10HOMEPAGE= https://www.loudmouth-project.org/ 10HOMEPAGE= https://github.com/mcabber/loudmouth
11COMMENT= Lightweight Jabber client library 11COMMENT= Lightweight Jabber client library
12LICENSE= gnu-lgpl-v2.1 12LICENSE= gnu-lgpl-v2.1
13 13
14USE_LIBTOOL= yes 14USE_LIBTOOL= yes
15USE_TOOLS+= gmake pkg-config 15USE_TOOLS+= gmake pkg-config
16GNU_CONFIGURE= yes 16GNU_CONFIGURE= yes
17CONFIGURE_ARGS+= --disable-debug 17CONFIGURE_ARGS+= --disable-debug
18CONFIGURE_ARGS+= --disable-gtk-doc 18CONFIGURE_ARGS+= --disable-gtk-doc
19CONFIGURE_ARGS+= --with-ssl=openssl 19CONFIGURE_ARGS+= --with-ssl=openssl
20 20
21PKGCONFIG_OVERRIDE+= loudmouth-1.0.pc.in 21PKGCONFIG_OVERRIDE+= loudmouth-1.0.pc.in
22 22
23.include "../../converters/libiconv/buildlink3.mk" 23.include "../../converters/libiconv/buildlink3.mk"

cvs diff -r1.21 -r1.22 pkgsrc/chat/loudmouth/distinfo (expand / switch to unified diff)

--- pkgsrc/chat/loudmouth/distinfo 2020/06/29 23:35:51 1.21
+++ pkgsrc/chat/loudmouth/distinfo 2021/01/23 09:08:07 1.22
@@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
1$NetBSD: distinfo,v 1.21 2020/06/29 23:35:51 gutteridge Exp $ 1$NetBSD: distinfo,v 1.22 2021/01/23 09:08:07 wiz Exp $
2 2
3SHA1 (loudmouth-1.5.3.tar.bz2) = a69ef9a57e0ae993340921e73ada27979850db04 3SHA1 (loudmouth-1.5.3.tar.bz2) = a69ef9a57e0ae993340921e73ada27979850db04
4RMD160 (loudmouth-1.5.3.tar.bz2) = aba3fc803a87e334b09987e27a5f841a46761dd8 4RMD160 (loudmouth-1.5.3.tar.bz2) = aba3fc803a87e334b09987e27a5f841a46761dd8
5SHA512 (loudmouth-1.5.3.tar.bz2) = ab6b16b4e644b69cdb7d8df1753d1bb5b43c2f1e76944e639339169b332e1b5c6a4246053c5b8a579ee9b53c845cef610b0040dfdffeb857180b6bab71adfcce 5SHA512 (loudmouth-1.5.3.tar.bz2) = ab6b16b4e644b69cdb7d8df1753d1bb5b43c2f1e76944e639339169b332e1b5c6a4246053c5b8a579ee9b53c845cef610b0040dfdffeb857180b6bab71adfcce
6Size (loudmouth-1.5.3.tar.bz2) = 375974 bytes 6Size (loudmouth-1.5.3.tar.bz2) = 375974 bytes
7SHA1 (patch-loudmouth_lm-resolver.c) = c16eb618dded2158bceac511a96c0b7535177b80 7SHA1 (patch-loudmouth_lm-resolver.c) = c16eb618dded2158bceac511a96c0b7535177b80
 8SHA1 (patch-loudmouth_lm-ssl-openssl.c) = 0aa1d4795579881b2633e620ff4267e78ea478fb

File Added: pkgsrc/chat/loudmouth/patches/Attic/patch-loudmouth_lm-ssl-openssl.c
$NetBSD: patch-loudmouth_lm-ssl-openssl.c,v 1.1 2021/01/23 09:08:07 wiz Exp $

From 792d8bd529f5dc0577dcc28c5f31b6a437d970fa Mon Sep 17 00:00:00 2001
From: tmp170422 <tmp131110@ya.ru>
Date: Sat, 22 Apr 2017 18:30:57 +0300
Subject: [PATCH] Fix an issue with wildcard domain names in CN

When CN contains wildcards, the SAN list would be checked against corrupt server name.
---
 loudmouth/lm-ssl-openssl.c | 121 +++++++++++++++++++++----------------
 1 file changed, 69 insertions(+), 52 deletions(-)

https://github.com/mcabber/loudmouth/commit/792d8bd529f5dc0577dcc28c5f31b6a437d970fa.patch

with a manual compilation fix (missing ')')

--- loudmouth/lm-ssl-openssl.c.orig	2016-02-14 17:05:11.000000000 +0000
+++ loudmouth/lm-ssl-openssl.c
@@ -118,11 +118,35 @@ ssl_verify_cb (int preverify_ok, X509_ST
     return 1;
 }
 
+static gboolean
+ssl_match_domain_name (const gchar *server, const gchar *domain)
+{
+    if (domain[0]=='*' && domain[1]=='.') {
+        /* leftmost part wildcard */
+        ++domain;
+
+        if (strchr(domain, '*') != NULL) {
+            /* multiple wildcards not allowed */
+            return FALSE;
+        }
+
+        server = strchr(server, '.'); /* eat the leftmost part */
+        if (server == NULL) {
+            return FALSE;
+        }
+
+        /* fall thru for wildcard match */
+    }
+
+    return (!strcasecmp(server, domain));
+}
+
 /* side effect: fills the ssl->fingerprint buffer */
 static gboolean
 ssl_verify_certificate (LmSSL *ssl, const gchar *server)
 {
     gboolean retval = TRUE;
+    gboolean match_result = FALSE;
     LmSSLBase *base;
     long verify_res;
     int rc;
@@ -219,70 +243,63 @@ ssl_verify_certificate (LmSSL *ssl, cons
 
     /* FWB: deprecated call, can only get first entry */
     if (X509_NAME_get_text_by_NID(crt_subj, NID_commonName, cn, LM_SSL_CN_MAX) > 0) {
-        gchar *domain = cn;
 
         g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL,
                "%s: server = '%s', cn = '%s'\n",
                __FILE__, server, cn);
 
-        if (domain != NULL) {
-
-            if ((cn[0] == '*') && (cn[1] == '.')) {
-                /*
-                 * FWB: huh? ever tested?
-                 * server="sub.domain.tld";
-                 * cn="*.domain.tld";
-                 * domain=strstr(cn, server); ???
-                 */
-                /* domain = strstr (cn, server); */
-                server = strchr(server, '.') + 1;
-                domain = cn + 2;
-            }
-
-            if (strncasecmp (server, domain, LM_SSL_CN_MAX) != 0) {
-                /* FWB: CN doesn't match, try SANs */
-                int subject_alt_names_nb = -1;
-                int san_result = 0;
-                int san_counter;
-                STACK_OF(GENERAL_NAME) *subject_alt_names = NULL;
-
-                /* g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: CN does not match server name\n", __FILE__); */
-                // Try to extract the names within the SAN extension from the certificate
-                subject_alt_names = X509_get_ext_d2i((X509 *) srv_crt, NID_subject_alt_name, NULL, NULL);
-                if (subject_alt_names != NULL) {
-
-                    // Check each name within the extension
-                    subject_alt_names_nb = sk_GENERAL_NAME_num(subject_alt_names);
-                    for (san_counter=0; san_counter<subject_alt_names_nb; san_counter++) {
-                        const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(subject_alt_names, san_counter);
-                        if (current_name->type == GEN_DNS) {
-                            // Current name is a DNS name, let's check it, it's ASCII
-                            if (strcasecmp(server, (char *)current_name->d.dNSName->data) == 0) {
-                                g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: found SAN '%s' - MATCH\n", __FILE__, current_name->d.dNSName->data);
-                                san_result = 1; /* break; */
-                            } else {
-                                g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: found SAN '%s'\n", __FILE__, current_name->d.dNSName->data);
-                            }
-                        }
-                    }
-
-                }
-                sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free);
-                if (!san_result) goto cn_and_san_mismatch;
-            } /* SAN */
+        if (cn != NULL && ssl_match_domain_name(server, cn)) {
+            match_result = TRUE;
         } else {
-            cn_and_san_mismatch:
-            if (base->func (ssl,
-                            LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
-                            base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
-                retval = FALSE;
-            }
+            /* g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: CN does not match server name\n", __FILE__); */
         }
     } else {
         g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL,
                "X509_NAME_get_text_by_NID() failed");
     }
 
+    /* RFC6125: "...However, it is perfectly acceptable for the subject field to be empty,
+     * as long as the certificate contains a subject alternative name ("subjectAltName")
+     * extension that includes at least one subjectAltName entry"
+     */
+    if (!match_result) {
+        /* FWB: CN doesn't match, try SANs */
+        int subject_alt_names_nb = -1;
+        int san_counter;
+        STACK_OF(GENERAL_NAME) *subject_alt_names = NULL;
+
+        // Try to extract the names within the SAN extension from the certificate
+        subject_alt_names = X509_get_ext_d2i((X509 *) srv_crt, NID_subject_alt_name, NULL, NULL);
+        if (subject_alt_names != NULL) {
+
+            // Check each name within the extension
+            subject_alt_names_nb = sk_GENERAL_NAME_num(subject_alt_names);
+            for (san_counter=0; san_counter<subject_alt_names_nb; san_counter++) {
+                const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(subject_alt_names, san_counter);
+                if (current_name->type == GEN_DNS) {
+                    // Current name is a DNS name, let's check it, it's ASCII
+                    if (ssl_match_domain_name(server, (const char *)current_name->d.dNSName->data)) {
+                        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: found SAN '%s' - MATCH\n", __FILE__, current_name->d.dNSName->data);
+                        match_result = TRUE; /* break; */
+                    } else {
+                        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL, "%s: found SAN '%s'\n", __FILE__, current_name->d.dNSName->data);
+                    }
+                }
+            }
+
+        }
+
+        sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free);
+    }
+
+    if (!match_result) {
+        if (base->func (ssl,
+                        LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
+                        base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
+            retval = FALSE;
+        }
+    }
+
     g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SSL,
            "%s:\n\tIssuer: %s\n\tSubject: %s\n\tFor: %s\n",
            __FILE__,