5 Commits

Author SHA1 Message Date
fe9a2ee202 Preparation for 2.18.3 2026-06-29 20:49:41 -06:00
deepend-tildeclub
5e27dc7e9f Merge pull request #315 from ZoiteChat/python-script-compatibility-fix
Snapshot Python hooks during plugin unload
2026-06-29 20:41:00 -06:00
deepend-tildeclub
69d083e3c0 Merge pull request #314 from ZoiteChat/openssl4-build-fixes
Support OpenSSL 4 APIs
2026-06-29 20:38:39 -06:00
2b95f9724e Snapshot Python hooks during plugin unload 2026-06-29 19:13:18 -06:00
4066a07892 Support OpenSSL 4 API 2026-06-29 18:47:46 -06:00
7 changed files with 54 additions and 17 deletions

View File

@@ -1,6 +1,17 @@
ZoiteChat ChangeLog ZoiteChat ChangeLog
================= =================
2.18.3 (2026-06-29)
-------------------
- Added IRCv3 support for message tags, echo-message, typing notifications, and replies.
- Restored the accept-invalid-cert TLS bypass behavior.
- Replaced legacy IPv4 APIs and added support for OpenSSL 4 APIs.
- Snapshot Python hooks during plugin unload for safer plugin shutdown.
- Fixed Windows GtkStatusIcon tray menu popup behavior.
- Fixed self-echoed private messages routing to the target tab.
- Fixed the lag ping timeout window.
2.18.2 (2026-06-20) 2.18.2 (2026-06-20)
------------------- -------------------

View File

@@ -29,6 +29,19 @@
<id>zoitechat.desktop</id> <id>zoitechat.desktop</id>
</provides> </provides>
<releases> <releases>
<release date="2026-06-29" version="2.18.3">
<description>
<ul>
<li>Added IRCv3 support for message tags, echo-message, typing notifications, and replies.</li>
<li>Restored the accept-invalid-cert TLS bypass behavior.</li>
<li>Replaced legacy IPv4 APIs and added support for OpenSSL 4 APIs.</li>
<li>Snapshot Python hooks during plugin unload for safer plugin shutdown.</li>
<li>Fixed Windows GtkStatusIcon tray menu popup behavior.</li>
<li>Fixed self-echoed private messages routing to the target tab.</li>
<li>Fixed the lag ping timeout window.</li>
</ul>
</description>
</release>
<release date="2026-06-20" version="2.18.2"> <release date="2026-06-20" version="2.18.2">
<description> <description>
<p>Security and connections:</p> <p>Security and connections:</p>

View File

@@ -1,5 +1,5 @@
project('zoitechat', 'c', project('zoitechat', 'c',
version: '2.18.2', version: '2.18.3',
meson_version: '>= 0.55.0', meson_version: '>= 0.55.0',
default_options: [ default_options: [
'c_std=c17', 'c_std=c17',

View File

@@ -1,5 +1,5 @@
Name: zoitechat Name: zoitechat
Version: 2.18.2 Version: 2.18.3
Release: %autorelease Release: %autorelease
Summary: HexChat-based IRC client Summary: HexChat-based IRC client
License: GPL-2.0-or-later WITH cryptsetup-OpenSSL-exception License: GPL-2.0-or-later WITH cryptsetup-OpenSSL-exception

View File

@@ -19,7 +19,7 @@ else:
if not hasattr(sys, 'argv'): if not hasattr(sys, 'argv'):
sys.argv = ['<zoitechat>'] sys.argv = ['<zoitechat>']
VERSION = b'2.18.2' VERSION = b'2.18.3'
PLUGIN_NAME = ffi.new('char[]', b'Python') PLUGIN_NAME = ffi.new('char[]', b'Python')
PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1])) PLUGIN_DESC = ffi.new('char[]', b'Python %d.%d scripting interface' % (sys.version_info[0], sys.version_info[1]))
PLUGIN_VERSION = ffi.new('char[]', VERSION) PLUGIN_VERSION = ffi.new('char[]', VERSION)
@@ -173,7 +173,7 @@ class Plugin:
def __del__(self): def __del__(self):
log('unloading', self.filename) log('unloading', self.filename)
for hook in self.hooks: for hook in list(self.hooks):
if hook.is_unload is True: if hook.is_unload is True:
try: try:
hook.callback(hook.userdata) hook.callback(hook.userdata)

View File

@@ -154,7 +154,7 @@ int
_SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl) _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
{ {
X509 *peer_cert; X509 *peer_cert;
X509_PUBKEY *key; const X509_PUBKEY *key;
X509_ALGOR *algor = NULL; X509_ALGOR *algor = NULL;
EVP_PKEY *peer_pkey; EVP_PKEY *peer_pkey;
char notBefore[64]; char notBefore[64];
@@ -350,7 +350,7 @@ _SSL_close (SSL * ssl)
{ {
SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
SSL_free (ssl); SSL_free (ssl);
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if !defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef HAVE_ERR_REMOVE_THREAD_STATE #ifdef HAVE_ERR_REMOVE_THREAD_STATE
ERR_remove_thread_state (NULL); ERR_remove_thread_state (NULL);
#else #else
@@ -507,9 +507,12 @@ _SSL_check_subject_altname (X509 *cert, const char *host)
static int static int
_SSL_check_common_name (X509 *cert, const char *host) _SSL_check_common_name (X509 *cert, const char *host)
{ {
X509_NAME *name; const X509_NAME *name;
char *common_name = NULL; const X509_NAME_ENTRY *entry;
const ASN1_STRING *common_name_asn1;
const unsigned char *common_name;
int common_name_len; int common_name_len;
int common_name_index;
int rv = -1; int rv = -1;
GInetAddress *addr; GInetAddress *addr;
@@ -517,16 +520,27 @@ _SSL_check_common_name (X509 *cert, const char *host)
if (name == NULL) if (name == NULL)
return -1; return -1;
common_name_len = X509_NAME_get_text_by_NID (name, NID_commonName, NULL, 0); common_name_index = X509_NAME_get_index_by_NID (name, NID_commonName, -1);
if (common_name_len < 0) if (common_name_index < 0)
return -1; return -1;
common_name = g_malloc0 (common_name_len + 1); entry = X509_NAME_get_entry (name, common_name_index);
if (entry == NULL)
return -1;
X509_NAME_get_text_by_NID (name, NID_commonName, common_name, common_name_len + 1); common_name_asn1 = X509_NAME_ENTRY_get_data (entry);
if (common_name_asn1 == NULL)
return -1;
#ifdef HAVE_ASN1_STRING_GET0_DATA
common_name = ASN1_STRING_get0_data (common_name_asn1);
#else
common_name = ASN1_STRING_data (common_name_asn1);
#endif
common_name_len = ASN1_STRING_length (common_name_asn1);
/* NUL bytes in CN? */ /* NUL bytes in CN? */
if (common_name_len != (int)strlen(common_name)) if (common_name_len != (int)strlen((const char *)common_name))
{ {
g_warning ("NUL byte in Common Name field, probably a malicious certificate.\n"); g_warning ("NUL byte in Common Name field, probably a malicious certificate.\n");
rv = -2; rv = -2;
@@ -539,18 +553,17 @@ _SSL_check_common_name (X509 *cert, const char *host)
* We don't want to attempt wildcard matching against IP * We don't want to attempt wildcard matching against IP
* addresses, so perform a simple comparison here. * addresses, so perform a simple comparison here.
*/ */
if (g_strcmp0 (common_name, host) == 0) if (g_strcmp0 ((const char *)common_name, host) == 0)
rv = 0; rv = 0;
else else
rv = -1; rv = -1;
g_object_unref (addr); g_object_unref (addr);
} }
else if (_SSL_match_hostname (common_name, host) == 0) else if (_SSL_match_hostname ((const char *)common_name, host) == 0)
rv = 0; rv = 0;
out: out:
g_free(common_name);
return rv; return rv;
} }

View File

@@ -1 +1 @@
2.18.2 2.18.3