Skip to content

Commit

Permalink
loudmouth: add upstream patch fixing an SSL problem
Browse files Browse the repository at this point in the history
Requested by Adrian Immanuel Kiess in PR 55944.

New release requested upstream (mcabber/loudmouth#42)

Bump PKGREVISION.
  • Loading branch information
0-wiz-0 committed Jan 23, 2021
1 parent 9628cd3 commit 95a7682
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 4 deletions.
6 changes: 3 additions & 3 deletions chat/loudmouth/Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# $NetBSD: Makefile,v 1.50 2020/05/31 15:43:17 rillig Exp $
# $NetBSD: Makefile,v 1.51 2021/01/23 09:08:07 wiz Exp $

DISTNAME= loudmouth-1.5.3
PKGREVISION= 2
PKGREVISION= 3
CATEGORIES= chat
MASTER_SITES= https://mcabber.com/files/loudmouth/
EXTRACT_SUFX= .tar.bz2

MAINTAINER= [email protected]
HOMEPAGE= https://www.loudmouth-project.org/
HOMEPAGE= https://github.com/mcabber/loudmouth
COMMENT= Lightweight Jabber client library
LICENSE= gnu-lgpl-v2.1

Expand Down
3 changes: 2 additions & 1 deletion chat/loudmouth/distinfo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
$NetBSD: distinfo,v 1.21 2020/06/29 23:35:51 gutteridge Exp $
$NetBSD: distinfo,v 1.22 2021/01/23 09:08:07 wiz Exp $

SHA1 (loudmouth-1.5.3.tar.bz2) = a69ef9a57e0ae993340921e73ada27979850db04
RMD160 (loudmouth-1.5.3.tar.bz2) = aba3fc803a87e334b09987e27a5f841a46761dd8
SHA512 (loudmouth-1.5.3.tar.bz2) = ab6b16b4e644b69cdb7d8df1753d1bb5b43c2f1e76944e639339169b332e1b5c6a4246053c5b8a579ee9b53c845cef610b0040dfdffeb857180b6bab71adfcce
Size (loudmouth-1.5.3.tar.bz2) = 375974 bytes
SHA1 (patch-loudmouth_lm-resolver.c) = c16eb618dded2158bceac511a96c0b7535177b80
SHA1 (patch-loudmouth_lm-ssl-openssl.c) = 0aa1d4795579881b2633e620ff4267e78ea478fb
170 changes: 170 additions & 0 deletions chat/loudmouth/patches/patch-loudmouth_lm-ssl-openssl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
$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__,

0 comments on commit 95a7682

Please sign in to comment.