From 67b25fddf1429eb68e538ec0a7196599017f5d7e Mon Sep 17 00:00:00 2001 From: konsolebox Date: Wed, 25 Jan 2023 07:03:53 +0800 Subject: Add option to exclude nickname in window title (#2759) --- src/common/cfgfiles.c | 2 ++ src/common/hexchat.h | 1 + src/fe-gtk/maingui.c | 32 ++++++++++++++------------------ src/fe-gtk/setup.c | 1 + 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c index fdee9f2c..f0799de9 100644 --- a/src/common/cfgfiles.c +++ b/src/common/cfgfiles.c @@ -468,6 +468,7 @@ const struct prefs vars[] = {"gui_win_fullscreen", P_OFFINT (hex_gui_win_fullscreen), TYPE_INT}, {"gui_win_left", P_OFFINT (hex_gui_win_left), TYPE_INT}, {"gui_win_modes", P_OFFINT (hex_gui_win_modes), TYPE_BOOL}, + {"gui_win_nick", P_OFFINT (hex_gui_win_nick), TYPE_BOOL}, {"gui_win_save", P_OFFINT (hex_gui_win_save), TYPE_BOOL}, {"gui_win_state", P_OFFINT (hex_gui_win_state), TYPE_INT}, {"gui_win_swap", P_OFFINT (hex_gui_win_swap), TYPE_BOOL}, @@ -772,6 +773,7 @@ load_default_config(void) prefs.hex_gui_ulist_count = 1; prefs.hex_gui_ulist_icons = 1; prefs.hex_gui_ulist_style = 1; + prefs.hex_gui_win_nick = 1; prefs.hex_gui_win_save = 1; prefs.hex_input_filter_beep = 1; prefs.hex_input_flash_hilight = 1; diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 470dd4ad..1b86f588 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -150,6 +150,7 @@ struct hexchatprefs unsigned int hex_gui_ulist_style; unsigned int hex_gui_usermenu; unsigned int hex_gui_win_modes; + unsigned int hex_gui_win_nick; unsigned int hex_gui_win_save; unsigned int hex_gui_win_swap; unsigned int hex_gui_win_ucount; diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 61f59856..0da60b3e 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -399,27 +399,22 @@ fe_set_title (session *sess) _(DISPLAY_NAME)); break; case SESS_SERVER: - g_snprintf (tbuf, sizeof (tbuf), "%s @ %s - %s", - sess->server->nick, server_get_network (sess->server, TRUE), + g_snprintf (tbuf, sizeof (tbuf), "%s%s%s - %s", + prefs.hex_gui_win_nick ? sess->server->nick : "", + prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE), _(DISPLAY_NAME)); break; case SESS_CHANNEL: /* don't display keys in the titlebar */ - if (prefs.hex_gui_win_modes) - { g_snprintf (tbuf, sizeof (tbuf), - "%s @ %s / %s (%s) - %s", - sess->server->nick, server_get_network (sess->server, TRUE), - sess->channel, sess->current_modes ? sess->current_modes : "", - _(DISPLAY_NAME)); - } - else - { - g_snprintf (tbuf, sizeof (tbuf), - "%s @ %s / %s - %s", - sess->server->nick, server_get_network (sess->server, TRUE), - sess->channel, _(DISPLAY_NAME)); - } + "%s%s%s / %s%s%s%s - %s", + prefs.hex_gui_win_nick ? sess->server->nick : "", + prefs.hex_gui_win_nick ? " @ " : "", + server_get_network (sess->server, TRUE), sess->channel, + prefs.hex_gui_win_modes && sess->current_modes ? " (" : "", + prefs.hex_gui_win_modes && sess->current_modes ? sess->current_modes : "", + prefs.hex_gui_win_modes && sess->current_modes ? ")" : "", + _(DISPLAY_NAME)); if (prefs.hex_gui_win_ucount) { g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total); @@ -427,8 +422,9 @@ fe_set_title (session *sess) break; case SESS_NOTICES: case SESS_SNOTICES: - g_snprintf (tbuf, sizeof (tbuf), "%s @ %s (notices) - %s", - sess->server->nick, server_get_network (sess->server, TRUE), + g_snprintf (tbuf, sizeof (tbuf), "%s%s%s (notices) - %s", + prefs.hex_gui_win_nick ? sess->server->nick : "", + prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE), _(DISPLAY_NAME)); break; default: diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c index 2f0589bd..0e1dfde3 100644 --- a/src/fe-gtk/setup.c +++ b/src/fe-gtk/setup.c @@ -176,6 +176,7 @@ static const setting appearance_settings[] = {ST_HEADER, N_("Title Bar"),0,0,0}, {ST_TOGGLE, N_("Show channel modes"), P_OFFINTNL(hex_gui_win_modes),0,0,0}, {ST_TOGGLR, N_("Show number of users"), P_OFFINTNL(hex_gui_win_ucount),0,0,0}, + {ST_TOGGLE, N_("Show nickname"), P_OFFINTNL(hex_gui_win_nick),0,0,0}, {ST_END, 0, 0, 0, 0, 0} }; -- cgit 1.4.1 From 7b093eea917374cb7b11fdfb9a332f4a61b789fb Mon Sep 17 00:00:00 2001 From: Colby <60820431+ComputerTech312@users.noreply.github.com> Date: Mon, 30 Jan 2023 15:29:49 +0000 Subject: Add TechNet to servlist --- src/common/servlist.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/servlist.c b/src/common/servlist.c index 771d7813..02341852 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -305,6 +305,9 @@ static const struct defaultserver def[] = {"Techtronix", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.techtronix.net"}, + {"TechNet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.technet.chat"}, + {"tilde.chat", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.tilde.chat"}, -- cgit 1.4.1 From c48afe3799e648e0ded2bf07deeb082028b6c5ac Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Tue, 14 Mar 2023 21:21:22 -0500 Subject: Be even more picky about invalid URLs --- src/fe-gtk/fe-gtk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index 38e6172d..125ab577 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -1065,8 +1065,7 @@ uri_contains_forbidden_characters (const char *uri) { while (*uri) { - /* This is not an exhaustive list, the full URI has segments that allow characters like "[]:" for example. */ - if (strchr ("`<> ${}\"+", *uri) != NULL || (*uri & 0x80) /* non-ascii */) + if (!g_ascii_isalnum (*uri) && !strchr ("-._~:/?#[]@!$&'()*+,;=", *uri)) return TRUE; uri++; } -- cgit 1.4.1 From 847e5a14d6d7991682c3add853f7b3cc32f935df Mon Sep 17 00:00:00 2001 From: Celelibi Date: Mon, 3 Apr 2023 05:22:12 +0200 Subject: python: add flush() to Stdout Python sometime calls flush() on sys.stdout or sys.stderr. In particular, it might do so when an exception is raised. This fixes the second error message that was generated in such cases. Signed-off-by: Celelibi --- plugins/python/python.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/python/python.py b/plugins/python/python.py index 7a794784..07900eb2 100644 --- a/plugins/python/python.py +++ b/plugins/python/python.py @@ -64,6 +64,10 @@ class Stdout: else: self.buffer += string + def flush(self): + lib.hexchat_print(lib.ph, bytes(self.buffer)) + self.buffer = bytearray() + def isatty(self): return False -- cgit 1.4.1 From 5cbd2524dcedb995fc98403d1d73a3400e2cb935 Mon Sep 17 00:00:00 2001 From: Celelibi Date: Mon, 3 Apr 2023 05:25:47 +0200 Subject: python: fix for timers that unhook themselves The python plugin use weak references for hooks, which might let a necessary object disappear if the callback of a timer hook unhooks itself. Signed-off-by: Celelibi --- plugins/python/python.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/python/python.py b/plugins/python/python.py index 07900eb2..9eca7d6e 100644 --- a/plugins/python/python.py +++ b/plugins/python/python.py @@ -291,7 +291,15 @@ def _on_timer_hook(userdata): if hook.callback(hook.userdata) == True: return 1 - hook.is_unload = True # Don't unhook + try: + # Avoid calling hexchat_unhook twice if unnecessary + hook.is_unload = True + except ReferenceError: + # hook is a weak reference, it might have been destroyed by the callback + # in which case it has already been removed from hook.plugin.hooks and + # we wouldn't be able to test it with h == hook anyway. + return 0 + for h in hook.plugin.hooks: if h == hook: hook.plugin.hooks.remove(h) -- cgit 1.4.1 From 4ee23424040835733fcb14c9230eba011b5d2dbc Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Mon, 24 Oct 2022 20:38:24 -0500 Subject: checksum: Move checksum operation to a thread --- meson.build | 6 +- plugins/checksum/checksum.c | 249 ++++++++++++++++---------------------------- 2 files changed, 91 insertions(+), 164 deletions(-) diff --git a/meson.build b/meson.build index 8b0bd404..f187c4b2 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,7 @@ gnome = import('gnome') cc = meson.get_compiler('c') -libgio_dep = dependency('gio-2.0', version: '>= 2.34.0') +libgio_dep = dependency('gio-2.0', version: '>= 2.36.0') libgmodule_dep = dependency('gmodule-2.0') libcanberra_dep = dependency('libcanberra', version: '>= 0.22', @@ -47,8 +47,8 @@ config_h.set('G_DISABLE_SINGLE_INCLUDES', true) config_h.set('GTK_DISABLE_DEPRECATED', true) config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true) config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true) -config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_34') -config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_34') +config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_36') +config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_36') # Detected features config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr')) diff --git a/plugins/checksum/checksum.c b/plugins/checksum/checksum.c index 6aa64b64..2c64ce39 100644 --- a/plugins/checksum/checksum.c +++ b/plugins/checksum/checksum.c @@ -22,216 +22,150 @@ #include "config.h" -#include -#include -#include #include #include "hexchat-plugin.h" -#define BUFSIZE 32768 -#define DEFAULT_LIMIT 256 /* default size is 256 MiB */ -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_BUFFER_LENGTH 65 - static hexchat_plugin *ph; /* plugin handle */ static char name[] = "Checksum"; static char desc[] = "Calculate checksum for DCC file transfers"; -static char version[] = "3.1"; +static char version[] = "4.0"; static void -set_limit (char *size) +print_sha256_result (hexchat_context *ctx, gboolean send_message, const char *checksum, const char *filename, GError *error) { - int limit = atoi (size); - - if (limit > 0 && limit < INT_MAX) - { - if (hexchat_pluginpref_set_int (ph, "limit", limit)) - hexchat_printf (ph, "Checksum: File size limit has successfully been set to: %d MiB\n", limit); - else - hexchat_printf (ph, "Checksum: File access error while saving!\n"); - } + /* Context may have been destroyed. */ + /* FIXME: This could still send the PRIVMSG even if the context was closed. */ + if (!hexchat_set_context (ph, ctx)) + return; + + if (error) + hexchat_printf (ph, "Failed to create checksum for %s: %s", filename, error->message); + else if (send_message) + hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", hexchat_get_info (ph, "channel"), filename, checksum); else - { - hexchat_printf (ph, "Checksum: Invalid input!\n"); - } + hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", filename, checksum); } -static int -get_limit (void) +/* TODO: We could put more info in task data and share the same callback. */ +static void +on_received_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) { - int size = hexchat_pluginpref_get_int (ph, "limit"); + hexchat_context *ctx = user_data; + GError *error = NULL; + char *sha256 = NULL; + const char *filename = g_task_get_task_data (G_TASK (result)); - if (size <= 0 || size >= INT_MAX) - return DEFAULT_LIMIT; - else - return size; + sha256 = g_task_propagate_pointer (G_TASK (result), &error); + print_sha256_result (ctx, FALSE, sha256, filename, error); + + g_free (sha256); + g_clear_error (&error); } -static gboolean -check_limit (GFile *file) +static void +on_sent_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) { - GFileInfo *file_info; - goffset file_size; - - file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, - NULL, NULL); + hexchat_context *ctx = user_data; + GError *error = NULL; + char *sha256 = NULL; + const char *filename = g_task_get_task_data (G_TASK (result)); - if (!file_info) - return FALSE; + sha256 = g_task_propagate_pointer (G_TASK (result), &error); + print_sha256_result (ctx, TRUE, sha256, filename, error); - file_size = g_file_info_get_size (file_info); - g_object_unref (file_info); - - if (file_size > get_limit () * 1048576ll) - return FALSE; - - return TRUE; + g_free (sha256); + g_clear_error (&error); } -static gboolean -sha256_from_stream (GFileInputStream *file_stream, char out_buf[]) +static void +thread_sha256_file (GTask *task, GFile *file, gpointer task_data, GCancellable *cancellable) { GChecksum *checksum; - gssize bytes_read; - guint8 digest[SHA256_DIGEST_LENGTH]; - gsize digest_len = sizeof(digest); - guchar buffer[BUFSIZE]; - gsize i; + GFileInputStream *istream; + guint8 buffer[32768]; + GError *error = NULL; + gssize ret; + + istream = g_file_read (file, cancellable, &error); + if (error) { + g_task_return_error (task, error); + return; + } checksum = g_checksum_new (G_CHECKSUM_SHA256); - while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (file_stream), buffer, sizeof (buffer), NULL, NULL))) - { - if (bytes_read == -1) - { - g_checksum_free (checksum); - return FALSE; - } + while ((ret = g_input_stream_read (G_INPUT_STREAM (istream), buffer, sizeof(buffer), cancellable, &error)) > 0) + g_checksum_update (checksum, buffer, ret); - g_checksum_update (checksum, buffer, bytes_read); + if (error) { + g_checksum_free (checksum); + g_task_return_error (task, error); + return; } - g_checksum_get_digest (checksum, digest, &digest_len); + g_task_return_pointer (task, g_strdup (g_checksum_get_string (checksum)), g_free); g_checksum_free (checksum); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) - { - /* out_buf will be exactly SHA256_BUFFER_LENGTH including null */ - g_sprintf (out_buf + (i * 2), "%02x", digest[i]); - } - - return TRUE; -} - -static gboolean -sha256_from_file (char *filename, char out_buf[]) -{ - GFileInputStream *file_stream; - char *filename_fs; - GFile *file; - - filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL); - if (!filename_fs) - { - hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename); - return FALSE; - } - - file = g_file_new_for_path (filename_fs); - g_free (filename_fs); - if (!file) - { - hexchat_printf (ph, "Checksum: Failed to open %s\n", filename); - return FALSE; - } - - if (!check_limit (file)) - { - hexchat_printf (ph, "Checksum: %s is larger than size limit. You can increase it with /CHECKSUM SET.\n", filename); - g_object_unref (file); - return FALSE; - } - - file_stream = g_file_read (file, NULL, NULL); - if (!file_stream) - { - hexchat_printf (ph, "Checksum: Failed to read file %s\n", filename); - g_object_unref (file); - return FALSE; - } - - if (!sha256_from_stream (file_stream, out_buf)) - { - hexchat_printf (ph, "Checksum: Failed to generate checksum for %s\n", filename); - g_object_unref (file_stream); - g_object_unref (file); - return FALSE; - } - - g_object_unref (file_stream); - g_object_unref (file); - return TRUE; } static int dccrecv_cb (char *word[], void *userdata) { + GTask *task; + char *filename_fs; + GFile *file; + hexchat_context *ctx; const char *dcc_completed_dir; - char *filename, checksum[SHA256_BUFFER_LENGTH]; - - /* Print in the privmsg tab of the sender */ - hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); + char *filename; if (hexchat_get_prefs (ph, "dcc_completed_dir", &dcc_completed_dir, NULL) == 1 && dcc_completed_dir[0] != '\0') filename = g_build_filename (dcc_completed_dir, word[1], NULL); else filename = g_strdup (word[2]); - if (sha256_from_file (filename, checksum)) - { - hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], checksum); + filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL); + if (!filename_fs) { + hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename); + g_free (filename); + return HEXCHAT_EAT_NONE; } - g_free (filename); + /* Print in the privmsg tab of the sender */ + ctx = hexchat_find_context (ph, NULL, word[3]); + + file = g_file_new_for_path (filename_fs); + task = g_task_new (file, NULL, (GAsyncReadyCallback) on_received_file_sha256_complete, ctx); + g_task_set_task_data (task, filename, g_free); + g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file); + + g_free (filename_fs); + g_object_unref (file); + g_object_unref (task); + return HEXCHAT_EAT_NONE; } static int dccoffer_cb (char *word[], void *userdata) { - char checksum[SHA256_BUFFER_LENGTH]; + GFile *file; + GTask *task; + hexchat_context *ctx; + char *filename; /* Print in the privmsg tab of the receiver */ - hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); - - if (sha256_from_file (word[3], checksum)) - { - hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], checksum); - } + ctx = hexchat_find_context (ph, NULL, word[3]); - return HEXCHAT_EAT_NONE; -} + filename = g_strdup (word[3]); + file = g_file_new_for_path (filename); + task = g_task_new (file, NULL, (GAsyncReadyCallback) on_sent_file_sha256_complete, ctx); + g_task_set_task_data (task, filename, g_free); + g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file); -static int -checksum (char *word[], char *word_eol[], void *userdata) -{ - if (!g_ascii_strcasecmp ("GET", word[2])) - { - hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ()); - } - else if (!g_ascii_strcasecmp ("SET", word[2])) - { - set_limit (word[3]); - } - else - { - hexchat_printf (ph, "Usage: /CHECKSUM GET|SET\n"); - hexchat_printf (ph, " GET - print the maximum file size (in MiB) to be hashed\n"); - hexchat_printf (ph, " SET - set the maximum file size (in MiB) to be hashed\n"); - } + g_object_unref (file); + g_object_unref (task); - return HEXCHAT_EAT_ALL; + return HEXCHAT_EAT_NONE; } int @@ -243,13 +177,6 @@ hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **p *plugin_desc = desc; *plugin_version = version; - /* this is required for the very first run */ - if (hexchat_pluginpref_get_int (ph, "limit") == -1) - { - hexchat_pluginpref_set_int (ph, "limit", DEFAULT_LIMIT); - } - - hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", NULL); hexchat_hook_print (ph, "DCC RECV Complete", HEXCHAT_PRI_NORM, dccrecv_cb, NULL); hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_NORM, dccoffer_cb, NULL); -- cgit 1.4.1 From 3dc18ff6fbe550c113d44df9b313d23ed965fdfc Mon Sep 17 00:00:00 2001 From: Totto16 Date: Mon, 3 Apr 2023 22:51:23 +0200 Subject: checksum: fixed the TODO and FIXME, tested and improved info message printing --- plugins/checksum/checksum.c | 89 +++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/plugins/checksum/checksum.c b/plugins/checksum/checksum.c index 2c64ce39..b27ad17b 100644 --- a/plugins/checksum/checksum.c +++ b/plugins/checksum/checksum.c @@ -31,49 +31,59 @@ static char name[] = "Checksum"; static char desc[] = "Calculate checksum for DCC file transfers"; static char version[] = "4.0"; -static void -print_sha256_result (hexchat_context *ctx, gboolean send_message, const char *checksum, const char *filename, GError *error) -{ - /* Context may have been destroyed. */ - /* FIXME: This could still send the PRIVMSG even if the context was closed. */ - if (!hexchat_set_context (ph, ctx)) - return; - if (error) - hexchat_printf (ph, "Failed to create checksum for %s: %s", filename, error->message); - else if (send_message) - hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", hexchat_get_info (ph, "channel"), filename, checksum); - else - hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", filename, checksum); -} +typedef struct { + gboolean send_message; + GString *servername; + GString *channel; +} ChecksumCallbackInfo; + -/* TODO: We could put more info in task data and share the same callback. */ static void -on_received_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) +print_sha256_result (ChecksumCallbackInfo *info, const char *checksum, const char *filename, GError *error) { - hexchat_context *ctx = user_data; - GError *error = NULL; - char *sha256 = NULL; - const char *filename = g_task_get_task_data (G_TASK (result)); - sha256 = g_task_propagate_pointer (G_TASK (result), &error); - print_sha256_result (ctx, FALSE, sha256, filename, error); + // So then we get the next best available channel, since we always want to print at least somewhere, it's fine + hexchat_context *ctx = hexchat_find_context(ph, info->servername->str, info->channel->str); + if (!ctx) { + // before we print a private message to the wrong channel, we exit early + if (info->send_message) { + return; + } + + // if the context isn't found the first time, we search in the server + ctx = hexchat_find_context(ph, info->servername->str, NULL); + if (!ctx) { + //the second time we exit early, since printing in another server isn't desireable + return; + } + } - g_free (sha256); - g_clear_error (&error); + hexchat_set_context(ph, ctx); + + if (error) { + hexchat_printf (ph, "Failed to create checksum for %s: %s\n", filename, error->message); + } else if (info->send_message) { + hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", hexchat_get_info (ph, "channel"), filename, checksum); + } else { + hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", filename, checksum); + } } static void -on_sent_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) -{ - hexchat_context *ctx = user_data; +file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) +{ + ChecksumCallbackInfo * callback_info = user_data; GError *error = NULL; char *sha256 = NULL; const char *filename = g_task_get_task_data (G_TASK (result)); sha256 = g_task_propagate_pointer (G_TASK (result), &error); - print_sha256_result (ctx, TRUE, sha256, filename, error); + print_sha256_result (callback_info, sha256, filename, error); + g_string_free(callback_info->servername, TRUE); + g_string_free(callback_info->channel, TRUE); + g_free(callback_info); g_free (sha256); g_clear_error (&error); } @@ -114,7 +124,6 @@ dccrecv_cb (char *word[], void *userdata) GTask *task; char *filename_fs; GFile *file; - hexchat_context *ctx; const char *dcc_completed_dir; char *filename; @@ -130,11 +139,16 @@ dccrecv_cb (char *word[], void *userdata) return HEXCHAT_EAT_NONE; } - /* Print in the privmsg tab of the sender */ - ctx = hexchat_find_context (ph, NULL, word[3]); + ChecksumCallbackInfo *callback_data = g_new (ChecksumCallbackInfo, 1); + const char* servername = hexchat_get_info(ph, "server"); + callback_data->servername = !servername ? NULL : g_string_new(servername); + const char *channel = hexchat_get_info(ph, "channel"); + callback_data->channel = !channel ? NULL : g_string_new(channel); + callback_data->send_message = FALSE; + file = g_file_new_for_path (filename_fs); - task = g_task_new (file, NULL, (GAsyncReadyCallback) on_received_file_sha256_complete, ctx); + task = g_task_new (file, NULL, (GAsyncReadyCallback) file_sha256_complete, (gpointer)callback_data); g_task_set_task_data (task, filename, g_free); g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file); @@ -150,15 +164,18 @@ dccoffer_cb (char *word[], void *userdata) { GFile *file; GTask *task; - hexchat_context *ctx; char *filename; - /* Print in the privmsg tab of the receiver */ - ctx = hexchat_find_context (ph, NULL, word[3]); + ChecksumCallbackInfo *callback_data = g_new (ChecksumCallbackInfo, 1); + const char* servername = hexchat_get_info(ph, "server"); + callback_data->servername = !servername ? NULL : g_string_new(servername); + const char *channel = hexchat_get_info(ph, "channel"); + callback_data->channel = !channel ? NULL : g_string_new(channel); + callback_data->send_message = TRUE; filename = g_strdup (word[3]); file = g_file_new_for_path (filename); - task = g_task_new (file, NULL, (GAsyncReadyCallback) on_sent_file_sha256_complete, ctx); + task = g_task_new (file, NULL, (GAsyncReadyCallback) file_sha256_complete, (gpointer)callback_data); g_task_set_task_data (task, filename, g_free); g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file); -- cgit 1.4.1 From a01d9ea1528a33dfc8706b391324ef50afc97991 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Mon, 1 May 2023 14:27:29 -0500 Subject: checksum: Replace GString usage with regular strings --- plugins/checksum/checksum.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/plugins/checksum/checksum.c b/plugins/checksum/checksum.c index b27ad17b..4db14c93 100644 --- a/plugins/checksum/checksum.c +++ b/plugins/checksum/checksum.c @@ -34,17 +34,16 @@ static char version[] = "4.0"; typedef struct { gboolean send_message; - GString *servername; - GString *channel; + char *servername; + char *channel; } ChecksumCallbackInfo; static void print_sha256_result (ChecksumCallbackInfo *info, const char *checksum, const char *filename, GError *error) { - // So then we get the next best available channel, since we always want to print at least somewhere, it's fine - hexchat_context *ctx = hexchat_find_context(ph, info->servername->str, info->channel->str); + hexchat_context *ctx = hexchat_find_context(ph, info->servername, info->channel); if (!ctx) { // before we print a private message to the wrong channel, we exit early if (info->send_message) { @@ -52,9 +51,9 @@ print_sha256_result (ChecksumCallbackInfo *info, const char *checksum, const cha } // if the context isn't found the first time, we search in the server - ctx = hexchat_find_context(ph, info->servername->str, NULL); + ctx = hexchat_find_context(ph, info->servername, NULL); if (!ctx) { - //the second time we exit early, since printing in another server isn't desireable + // The second time we exit early, since printing in another server isn't desireable return; } } @@ -81,8 +80,8 @@ file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data) sha256 = g_task_propagate_pointer (G_TASK (result), &error); print_sha256_result (callback_info, sha256, filename, error); - g_string_free(callback_info->servername, TRUE); - g_string_free(callback_info->channel, TRUE); + g_free(callback_info->servername); + g_free(callback_info->channel); g_free(callback_info); g_free (sha256); g_clear_error (&error); @@ -140,12 +139,10 @@ dccrecv_cb (char *word[], void *userdata) } ChecksumCallbackInfo *callback_data = g_new (ChecksumCallbackInfo, 1); - const char* servername = hexchat_get_info(ph, "server"); - callback_data->servername = !servername ? NULL : g_string_new(servername); - const char *channel = hexchat_get_info(ph, "channel"); - callback_data->channel = !channel ? NULL : g_string_new(channel); + callback_data->servername = g_strdup(hexchat_get_info(ph, "server")); + callback_data->channel = g_strdup(hexchat_get_info(ph, "channel")); callback_data->send_message = FALSE; - + file = g_file_new_for_path (filename_fs); task = g_task_new (file, NULL, (GAsyncReadyCallback) file_sha256_complete, (gpointer)callback_data); @@ -167,10 +164,8 @@ dccoffer_cb (char *word[], void *userdata) char *filename; ChecksumCallbackInfo *callback_data = g_new (ChecksumCallbackInfo, 1); - const char* servername = hexchat_get_info(ph, "server"); - callback_data->servername = !servername ? NULL : g_string_new(servername); - const char *channel = hexchat_get_info(ph, "channel"); - callback_data->channel = !channel ? NULL : g_string_new(channel); + callback_data->servername = g_strdup(hexchat_get_info(ph, "server")); + callback_data->channel = g_strdup(hexchat_get_info(ph, "channel")); callback_data->send_message = TRUE; filename = g_strdup (word[3]); -- cgit 1.4.1 From 6155c18315556a4ee4e59c3f61a0d95b96deae41 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 21 Jun 2023 19:05:08 -0500 Subject: servlist: Update UnderNet hostname Closes #2786 --- src/common/servlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/servlist.c b/src/common/servlist.c index 02341852..1f29bb32 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -326,7 +326,7 @@ static const struct defaultserver def[] = #endif {"UnderNet", 0, 0, 0, LOGIN_CUSTOM, "MSG x@channels.undernet.org login %u %p"}, - {0, "us.undernet.org"}, + {0, "irc.undernet.org"}, {"Xertion", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.xertion.org"}, -- cgit 1.4.1 From cda96128b8baf0675e74f650e97818de6ec53c6b Mon Sep 17 00:00:00 2001 From: Matr1x-101 <70490301+Matr1x-101@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:48:37 +0100 Subject: Add description for .desktop file for HexChat thememan (#2791) --- data/misc/io.github.Hexchat.ThemeManager.desktop.in | 1 + 1 file changed, 1 insertion(+) diff --git a/data/misc/io.github.Hexchat.ThemeManager.desktop.in b/data/misc/io.github.Hexchat.ThemeManager.desktop.in index 53cac289..705f24ba 100644 --- a/data/misc/io.github.Hexchat.ThemeManager.desktop.in +++ b/data/misc/io.github.Hexchat.ThemeManager.desktop.in @@ -1,5 +1,6 @@ [Desktop Entry] Name=HexChat Theme Manager +Comment=A simple theme manager for HexChat Exec=thememan %f Icon=hexchat Terminal=false -- cgit 1.4.1 From a1f154cd5ee63ec6b9ac154b8dc6d5a5d97c2c28 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Fri, 3 Nov 2023 10:58:56 -0500 Subject: win32: Remove Python 2 support --- .github/workflows/windows-build.yml | 3 -- plugins/python/python2.vcxproj | 65 ---------------------------------- plugins/python/python2.vcxproj.filters | 23 ------------ src/common/plugin.c | 1 - win32/copy/copy.vcxproj | 1 - win32/hexchat.props | 4 --- win32/hexchat.sln | 11 ------ win32/installer/hexchat.iss.tt | 16 ++------- 8 files changed, 3 insertions(+), 121 deletions(-) delete mode 100644 plugins/python/python2.vcxproj delete mode 100644 plugins/python/python2.vcxproj.filters diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 4554f2a9..18aca7ca 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -40,13 +40,10 @@ jobs: Invoke-WebRequest https://dl.hexchat.net/misc/perl/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} - New-Item -Path "c:\gtk-build" -Name "python-2.7" -ItemType "Directory" New-Item -Path "c:\gtk-build" -Name "python-3.8" -ItemType "Directory" - New-Item -Path "c:\gtk-build\python-2.7" -Name "${{ matrix.platform }}" -ItemType "SymbolicLink" -Value "C:/hostedtoolcache/windows/Python/2.7.18/${{ matrix.arch }}" New-Item -Path "c:\gtk-build\python-3.8" -Name "${{ matrix.platform }}" -ItemType "SymbolicLink" -Value "C:/hostedtoolcache/windows/Python/3.8.10/${{ matrix.arch }}" C:/hostedtoolcache/windows/Python/3.8.10/${{ matrix.arch }}/python.exe -m pip install cffi - C:/hostedtoolcache/windows/Python/2.7.18/${{ matrix.arch }}/python.exe -m pip install -qq cffi shell: powershell - name: Build diff --git a/plugins/python/python2.vcxproj b/plugins/python/python2.vcxproj deleted file mode 100644 index 42895ce4..00000000 --- a/plugins/python/python2.vcxproj +++ /dev/null @@ -1,65 +0,0 @@ - - - - v142 - DynamicLibrary - - - - Release - Win32 - - - Release - x64 - - - - {19C52A0A-A790-409E-A28A-9745FF990F5C} - Win32Proj - python2 - - - - - - - $(Python2Output) - $(HexChatRel)plugins\ - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(Glib);$(Python2Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories) - - - python.def - "$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies) - $(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories) - - - "$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c" - - - - - WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions) - $(Glib);$(Python2Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories) - - - python.def - "$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies) - $(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories) - - - "$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c" - - - - - - - - - - diff --git a/plugins/python/python2.vcxproj.filters b/plugins/python/python2.vcxproj.filters deleted file mode 100644 index d56e53b6..00000000 --- a/plugins/python/python2.vcxproj.filters +++ /dev/null @@ -1,23 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Resource Files - - - - - Source Files - - - \ No newline at end of file diff --git a/src/common/plugin.c b/src/common/plugin.c index 40e55bbf..536f376d 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -491,7 +491,6 @@ plugin_auto_load (session *sess) for_files (lib_dir, "hcfishlim.dll", plugin_auto_load_cb); for_files(lib_dir, "hclua.dll", plugin_auto_load_cb); for_files (lib_dir, "hcperl.dll", plugin_auto_load_cb); - for_files (lib_dir, "hcpython2.dll", plugin_auto_load_cb); for_files (lib_dir, "hcpython3.dll", plugin_auto_load_cb); for_files (lib_dir, "hcupd.dll", plugin_auto_load_cb); for_files (lib_dir, "hcwinamp.dll", plugin_auto_load_cb); diff --git a/win32/copy/copy.vcxproj b/win32/copy/copy.vcxproj index 2fc7437b..cb3ea1cf 100644 --- a/win32/copy/copy.vcxproj +++ b/win32/copy/copy.vcxproj @@ -65,7 +65,6 @@ - diff --git a/win32/hexchat.props b/win32/hexchat.props index 5d81b2dc..d6c2bf1a 100644 --- a/win32/hexchat.props +++ b/win32/hexchat.props @@ -7,7 +7,6 @@ c:\gtk-build\gtk c:\gtk-build\gendef c:\gtk-build\perl-5.20 - c:\gtk-build\python-2.7 c:\gtk-build\python-3.8 c:\gtk-build\WinSparkle @@ -22,9 +21,6 @@ $(YourWinSparklePath)\$(PlatformName) $(YourPerlPath)\$(PlatformName) perl520 - $(YourPython2Path)\$(PlatformName) - python27 - hcpython2 $(YourPython3Path)\$(PlatformName) python38 hcpython3 diff --git a/win32/hexchat.sln b/win32/hexchat.sln index 8759c59b..57476b02 100644 --- a/win32/hexchat.sln +++ b/win32/hexchat.sln @@ -21,11 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "plugins", "plugins", "{5611 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripting", "scripting", "{D237DA6B-BD5F-46C0-8BEA-50E9A1340240}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python2", "..\plugins\python\python2.vcxproj", "{19C52A0A-A790-409E-A28A-9745FF990F5C}" - ProjectSection(ProjectDependencies) = postProject - {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checksum", "..\plugins\checksum\checksum.vcxproj", "{5EF7F47D-D09C-43C4-BF64-B28B11A0FF91}" ProjectSection(ProjectDependencies) = postProject {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} @@ -72,7 +67,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer\installer.vcxproj", "{5A0F4962-E670-4DA2-9E45-52CC47F26E2F}" ProjectSection(ProjectDependencies) = postProject {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} = {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} - {19C52A0A-A790-409E-A28A-9745FF990F5C} = {19C52A0A-A790-409E-A28A-9745FF990F5C} {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A} = {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A} {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} = {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} {4C0F3940-2EEE-4646-82F7-6CE75B9A72F4} = {4C0F3940-2EEE-4646-82F7-6CE75B9A72F4} @@ -134,10 +128,6 @@ Global {E93E1255-95D1-4B08-8FDF-B53CC6A21280}.Release|Win32.Build.0 = Release|Win32 {E93E1255-95D1-4B08-8FDF-B53CC6A21280}.Release|x64.ActiveCfg = Release|x64 {E93E1255-95D1-4B08-8FDF-B53CC6A21280}.Release|x64.Build.0 = Release|x64 - {19C52A0A-A790-409E-A28A-9745FF990F5C}.Release|Win32.ActiveCfg = Release|Win32 - {19C52A0A-A790-409E-A28A-9745FF990F5C}.Release|Win32.Build.0 = Release|Win32 - {19C52A0A-A790-409E-A28A-9745FF990F5C}.Release|x64.ActiveCfg = Release|x64 - {19C52A0A-A790-409E-A28A-9745FF990F5C}.Release|x64.Build.0 = Release|x64 {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91}.Release|Win32.ActiveCfg = Release|Win32 {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91}.Release|Win32.Build.0 = Release|Win32 {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91}.Release|x64.ActiveCfg = Release|x64 @@ -206,7 +196,6 @@ Global {87554B59-006C-4D94-9714-897B27067BA3} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} {E4BDB4C8-2335-415A-ACEE-BA88B19BFE82} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} {E93E1255-95D1-4B08-8FDF-B53CC6A21280} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} - {19C52A0A-A790-409E-A28A-9745FF990F5C} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {3C4F42FC-292A-420B-B63D-C03DFBDD8E4E} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} diff --git a/win32/installer/hexchat.iss.tt b/win32/installer/hexchat.iss.tt index b03e2212..1b7c3209 100644 --- a/win32/installer/hexchat.iss.tt +++ b/win32/installer/hexchat.iss.tt @@ -75,9 +75,7 @@ Name: "plugins\winamp"; Description: "Winamp"; Types: custom; Flags: disablenoun Name: "langs"; Description: "Language Interfaces"; Types: custom; Flags: disablenouninstallwarning Name: "langs\lua"; Description: "Lua"; Types: normal custom; Flags: disablenouninstallwarning Name: "langs\perl"; Description: "Perl (requires Perl 5.20)"; Types: custom; Flags: disablenouninstallwarning -Name: "langs\python"; Description: "Python Interface"; Types: custom; Flags: disablenouninstallwarning -Name: "langs\python\python2"; Description: "Python (requires Python 2.7)"; Types: custom; Flags: disablenouninstallwarning exclusive -Name: "langs\python\python3"; Description: "Python (requires Python 3.8)"; Types: custom; Flags: disablenouninstallwarning exclusive +Name: "langs\python"; Description: "Python (requires Python 3.8)"; Types: custom; Flags: disablenouninstallwarning [Tasks] Name: portable; Description: "Yes"; GroupDescription: "Portable Mode: Stores configuration files within install directory for portable drives."; Flags: unchecked @@ -188,11 +186,8 @@ Source: "plugins\hcperl.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Co Source: "python\*.py"; DestDir: "{app}\python"; Flags: ignoreversion; Components: langs\python -Source: "plugins\hcpython2.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python2 -Source: "_cffi_backend.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python2 - -Source: "plugins\hcpython3.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python3 -Source: "_cffi_backend.cp3*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python3 +Source: "plugins\hcpython3.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python +Source: "_cffi_backend.cp3*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python Source: "hexchat.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "hexchat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xctext @@ -303,13 +298,11 @@ begin REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x64.exe'; REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x64.exe'; PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x64.msi'; - PY2 := 'https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi'; PY3 := 'https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe'; #else REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x86.exe'; REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x86.exe'; PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x86.msi'; - PY2 := 'https://www.python.org/ftp/python/2.7.18/python-2.7.18.msi'; PY3 := 'https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe'; #endif DOTNET := 'https://dl.hexchat.net/misc/dotnet_40.exe'; @@ -334,9 +327,6 @@ begin idpAddFile(PERL, ExpandConstant('{tmp}\perl.msi')) end; - if IsComponentSelected('langs\python\python2') and not CheckDLL('python27.dll') then - idpAddFile(PY2, ExpandConstant('{tmp}\python.msi')); - if IsComponentSelected('langs\python\python3') and not CheckDLL('python38.dll') then idpAddFile(PY3, ExpandConstant('{tmp}\python.exe')); end; -- cgit 1.4.1 From 44d14a436bf33c76288ca22bd9a787aca8120dd0 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Fri, 3 Nov 2023 14:13:36 -0500 Subject: CI: Reduce duplicate builds --- .github/workflows/flatpak-build.yml | 9 ++++++++- .github/workflows/msys-build.yml | 8 +++++++- .github/workflows/ubuntu-build.yml | 9 ++++++++- .github/workflows/windows-build.yml | 8 +++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.github/workflows/flatpak-build.yml b/.github/workflows/flatpak-build.yml index 66cd890b..2d4d62ba 100644 --- a/.github/workflows/flatpak-build.yml +++ b/.github/workflows/flatpak-build.yml @@ -1,5 +1,12 @@ name: Flatpak Build -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: + branches: + - master + jobs: flatpak_build: runs-on: ubuntu-latest diff --git a/.github/workflows/msys-build.yml b/.github/workflows/msys-build.yml index 580c6aef..08c029b1 100644 --- a/.github/workflows/msys-build.yml +++ b/.github/workflows/msys-build.yml @@ -1,5 +1,11 @@ name: MSYS2 Build -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: + branches: + - master jobs: msys2_build: diff --git a/.github/workflows/ubuntu-build.yml b/.github/workflows/ubuntu-build.yml index 0e8deb34..cb6b5faa 100644 --- a/.github/workflows/ubuntu-build.yml +++ b/.github/workflows/ubuntu-build.yml @@ -1,5 +1,12 @@ name: Ubuntu Build -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: + branches: + - master + jobs: ubuntu_build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 18aca7ca..3ba01e8b 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -1,5 +1,11 @@ name: Windows Build -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: + branches: + - master jobs: windows_build: -- cgit 1.4.1 From 50ca0d5b09db31a88f4798c87d9be71894edcfca Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Wed, 1 Nov 2023 17:15:23 +0100 Subject: Moved SASL PLAIN authentication to own function --- src/common/inbound.c | 64 ++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index a591dc48..78a126f7 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1901,6 +1901,38 @@ inbound_cap_list (server *serv, char *nick, char *extensions, NULL, NULL, 0, tags_data->timestamp); } +static void +plain_authenticate(server *serv, char *user, char *password) +{ + char *pass = encode_sasl_pass_plain (user, password); + + if (pass == NULL) + { + /* something went wrong abort */ + tcp_sendf (serv, "AUTHENTICATE *\r\n"); + return; + } + + /* long SASL passwords must be split into 400-byte chunks + https://ircv3.net/specs/extensions/sasl-3.1#the-authenticate-command */ + size_t pass_len = strlen (pass); + if (pass_len <= 400) + tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass); + else + { + size_t sent = 0; + while (sent < pass_len) + { + char *pass_chunk = g_strndup (pass + sent, 400); + tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass_chunk); + sent += 400; + g_free (pass_chunk); + } + } + if (pass_len % 400 == 0) + tcp_sendf (serv, "AUTHENTICATE +\r\n"); +} + void inbound_sasl_authenticate (server *serv, char *data) { @@ -1921,43 +1953,15 @@ inbound_sasl_authenticate (server *serv, char *data) switch (serv->sasl_mech) { case MECH_PLAIN: - pass = encode_sasl_pass_plain (user, serv->password); + plain_authenticate(serv, user, serv->password); break; #ifdef USE_OPENSSL case MECH_EXTERNAL: - pass = g_strdup ("+"); + tcp_sendf (serv, "AUTHENTICATE +\r\n"); break; #endif } - if (pass == NULL) - { - /* something went wrong abort */ - tcp_sendf (serv, "AUTHENTICATE *\r\n"); - return; - } - - /* long SASL passwords must be split into 400-byte chunks - https://ircv3.net/specs/extensions/sasl-3.1#the-authenticate-command */ - size_t pass_len = strlen (pass); - if (pass_len <= 400) - tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass); - else - { - size_t sent = 0; - while (sent < pass_len) - { - char *pass_chunk = g_strndup (pass + sent, 400); - tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass_chunk); - sent += 400; - g_free (pass_chunk); - } - } - if (pass_len % 400 == 0) - tcp_sendf (serv, "AUTHENTICATE +\r\n"); - g_free (pass); - - EMIT_SIGNAL_TIMESTAMP (XP_TE_SASLAUTH, serv->server_session, user, (char*)mech, NULL, NULL, 0, 0); } -- cgit 1.4.1 From 6420fd61174e6a8218bf2740605ceb9241eaf36f Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Wed, 1 Nov 2023 17:47:34 +0100 Subject: SSL compile fix --- src/common/outbound.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/outbound.c b/src/common/outbound.c index b9f88196..c82e23bd 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -3458,6 +3458,8 @@ cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[]) #ifdef USE_OPENSSL int use_ssl = TRUE; int use_ssl_noverify = FALSE; +#else + int use_ssl = FALSE; #endif int is_url = TRUE; server *serv = sess->server; -- cgit 1.4.1 From 9b76b557ecaece2a5fa862ea4dc75ed613e3fbf0 Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Wed, 1 Nov 2023 19:12:32 +0100 Subject: Added support for SCRAM-SHA-1, SCRAM-SHA-256 and SCRAM-SHA-512 --- po/de.po | 8 ++ po/en_GB.po | 8 ++ po/it.po | 8 ++ src/common/common.vcxproj | 2 + src/common/hexchat.h | 5 + src/common/inbound.c | 117 ++++++++++++++++- src/common/meson.build | 1 + src/common/scram.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++ src/common/scram.h | 51 ++++++++ src/common/server.c | 6 +- src/common/servlist.h | 3 + src/fe-gtk/servlistgui.c | 8 +- 12 files changed, 534 insertions(+), 6 deletions(-) create mode 100644 src/common/scram.c create mode 100644 src/common/scram.h diff --git a/po/de.po b/po/de.po index 6ea54e8b..d0e152ef 100644 --- a/po/de.po +++ b/po/de.po @@ -367,6 +367,14 @@ msgstr "Aufgelöst zu:" msgid "Looking up %s..." msgstr "Schlage %s nach …" +#: src/common/inbound.c:1992 +msgid "Could not create SCRAM session with digest %s" +msgstr "Es konnte keine SCRAM-Sitzung mit der Hashfunktion %s erstellt werden" + +#: src/common/inbound.c:2024 +msgid "SASL SCRAM authentication failed: %s" +msgstr "SASL SCRAM Authentifizierung fehlgeschlagen: %s" + #: src/common/notify.c:559 #, c-format msgid " %-20s online\n" diff --git a/po/en_GB.po b/po/en_GB.po index 4acd694a..99775c0e 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -346,6 +346,14 @@ msgstr "Resolved to:" msgid "Looking up %s..." msgstr "Looking up %s..." +#: src/common/inbound.c:1992 +msgid "Could not create SCRAM session with digest %s" +msgstr "Could not create SCRAM session with digest %s" + +#: src/common/inbound.c:2024 +msgid "SASL SCRAM authentication failed: %s" +msgstr "SASL SCRAM authentication failed: %s" + #: src/common/notify.c:559 #, c-format msgid " %-20s online\n" diff --git a/po/it.po b/po/it.po index 966c6dcf..76f04720 100644 --- a/po/it.po +++ b/po/it.po @@ -343,6 +343,14 @@ msgstr "Risolto a:" msgid "Looking up %s..." msgstr "Ricerca di %s..." +#: src/common/inbound.c:1992 +msgid "Could not create SCRAM session with digest %s" +msgstr "Impossibile creare una sessione SCRAM con la funzione hash %s" + +#: src/common/inbound.c:2024 +msgid "SASL SCRAM authentication failed: %s" +msgstr "SASL SCRAM autenticazione fallita: %s" + #: src/common/notify.c:559 #, c-format msgid " %-20s online\n" diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index bc191f43..c91d8cbb 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -36,6 +36,7 @@ + @@ -69,6 +70,7 @@ + diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 1b86f588..5ead96d1 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -41,6 +41,7 @@ #ifdef USE_OPENSSL #include /* SSL_() */ +#include "scram.h" #endif #ifdef __EMX__ /* for o/s 2 */ @@ -430,6 +431,9 @@ typedef struct session /* SASL Mechanisms */ #define MECH_PLAIN 0 #define MECH_EXTERNAL 1 +#define MECH_SCRAM_SHA_1 2 +#define MECH_SCRAM_SHA_256 3 +#define MECH_SCRAM_SHA_512 4 typedef struct server { @@ -585,6 +589,7 @@ typedef struct server #ifdef USE_OPENSSL unsigned int use_ssl:1; /* is server SSL capable? */ unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */ + scram_session *scram_session; /* session for SASL SCRAM authentication */ #endif } server; diff --git a/src/common/inbound.c b/src/common/inbound.c index 78a126f7..9b38f7c7 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1648,7 +1648,10 @@ inbound_identified (server *serv) /* 'MODE +e MYSELF' on freenode */ static const char *sasl_mechanisms[] = { "PLAIN", - "EXTERNAL" + "EXTERNAL", + "SCRAM-SHA-1", + "SCRAM-SHA-256", + "SCRAM-SHA-512" }; static void @@ -1689,6 +1692,12 @@ inbound_toggle_caps (server *serv, const char *extensions_str, gboolean enable) #ifdef USE_OPENSSL if (serv->loginmethod == LOGIN_SASLEXTERNAL) serv->sasl_mech = MECH_EXTERNAL; + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1) + serv->sasl_mech = MECH_SCRAM_SHA_1; + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256) + serv->sasl_mech = MECH_SCRAM_SHA_256; + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512) + serv->sasl_mech = MECH_SCRAM_SHA_512; #endif /* Mechanism either defaulted to PLAIN or server gave us list */ tcp_sendf (serv, "AUTHENTICATE %s\r\n", sasl_mechanisms[serv->sasl_mech]); @@ -1766,6 +1775,30 @@ get_supported_mech (server *serv, const char *list) break; } } + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1) + { + if (!strcmp(mechs[i], "SCRAM-SHA-1")) + { + ret = MECH_SCRAM_SHA_1; + break; + } + } + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256) + { + if (!strcmp(mechs[i], "SCRAM-SHA-256")) + { + ret = MECH_SCRAM_SHA_256; + break; + } + } + else if (serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512) + { + if (!strcmp(mechs[i], "SCRAM-SHA-512")) + { + ret = MECH_SCRAM_SHA_512; + break; + } + } else #endif if (!strcmp (mechs[i], "PLAIN")) @@ -1821,7 +1854,11 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str, /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ if (!g_strcmp0 (extension, "sasl") && - ((serv->loginmethod == LOGIN_SASL && strlen (serv->password) != 0) + (((serv->loginmethod == LOGIN_SASL + || serv->loginmethod == LOGIN_SASL_SCRAM_SHA_1 + || serv->loginmethod == LOGIN_SASL_SCRAM_SHA_256 + || serv->loginmethod == LOGIN_SASL_SCRAM_SHA_512) + && strlen (serv->password) != 0) || serv->loginmethod == LOGIN_SASLEXTERNAL)) { if (value) @@ -1902,7 +1939,7 @@ inbound_cap_list (server *serv, char *nick, char *extensions, } static void -plain_authenticate(server *serv, char *user, char *password) +plain_authenticate (server *serv, char *user, char *password) { char *pass = encode_sasl_pass_plain (user, password); @@ -1933,11 +1970,71 @@ plain_authenticate(server *serv, char *user, char *password) tcp_sendf (serv, "AUTHENTICATE +\r\n"); } +#ifdef USE_OPENSSL +/* + * Sends AUTHENTICATE messages to log in via SCRAM. + */ +static void +scram_authenticate (server *serv, const char *data, const char *digest, + const char *user, const char *password) +{ + char *encoded, *decoded, *output; + scram_status status; + size_t output_len; + gsize decoded_len; + + if (serv->scram_session == NULL) + { + serv->scram_session = scram_create_session (digest, user, password); + + if (serv->scram_session == NULL) + { + PrintTextf (serv->server_session, _("Could not create SCRAM session with digest %s"), digest); + g_warning ("Could not create SCRAM session with digest %s", digest); + tcp_sendf (serv, "AUTHENTICATE *\r\n"); + return; + } + } + + decoded = g_base64_decode (data, &decoded_len); + status = scram_process (serv->scram_session, decoded, &output, &output_len); + g_free (decoded); + + if (status == SCRAM_IN_PROGRESS) + { + // Authentication is still in progress + encoded = g_base64_encode ((guchar *) output, output_len); + tcp_sendf (serv, "AUTHENTICATE %s\r\n", encoded); + g_free (encoded); + g_free (output); + } + else if (status == SCRAM_SUCCESS) + { + // Authentication succeeded + tcp_sendf (serv, "AUTHENTICATE +\r\n"); + g_clear_pointer (&serv->scram_session, scram_free_session); + } + else if (status == SCRAM_ERROR) + { + // Authentication failed + tcp_sendf (serv, "AUTHENTICATE *\r\n"); + + if (serv->scram_session->error != NULL) + { + PrintTextf (serv->server_session, _("SASL SCRAM authentication failed: %s"), serv->scram_session->error); + g_info ("SASL SCRAM authentication failed: %s", serv->scram_session->error); + } + + g_clear_pointer (&serv->scram_session, scram_free_session); + } +} +#endif + void inbound_sasl_authenticate (server *serv, char *data) { ircnet *net = (ircnet*)serv->network; - char *user, *pass = NULL; + char *user; const char *mech = sasl_mechanisms[serv->sasl_mech]; /* Got a list of supported mechanisms from outdated inspircd @@ -1959,6 +2056,15 @@ inbound_sasl_authenticate (server *serv, char *data) case MECH_EXTERNAL: tcp_sendf (serv, "AUTHENTICATE +\r\n"); break; + case MECH_SCRAM_SHA_1: + scram_authenticate(serv, data, "SHA1", user, serv->password); + return; + case MECH_SCRAM_SHA_256: + scram_authenticate(serv, data, "SHA256", user, serv->password); + return; + case MECH_SCRAM_SHA_512: + scram_authenticate(serv, data, "SHA512", user, serv->password); + return; #endif } @@ -1969,6 +2075,9 @@ inbound_sasl_authenticate (server *serv, char *data) void inbound_sasl_error (server *serv) { +#ifdef USE_OPENSSL + g_clear_pointer (&serv->scram_session, scram_free_session); +#endif /* Just abort, not much we can do */ tcp_sendf (serv, "AUTHENTICATE *\r\n"); } diff --git a/src/common/meson.build b/src/common/meson.build index 84e2fca3..35db2c27 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -15,6 +15,7 @@ common_sources = [ 'plugin-identd.c', 'plugin-timer.c', 'proto-irc.c', + 'scram.c', 'server.c', 'servlist.c', 'text.c', diff --git a/src/common/scram.c b/src/common/scram.c new file mode 100644 index 00000000..529abd5d --- /dev/null +++ b/src/common/scram.c @@ -0,0 +1,323 @@ +/* HexChat + * Copyright (C) 2023 Patrick Okraku + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "hexchat.h" + +#ifdef USE_OPENSSL + +#include "scram.h" +#include +#include + +#define NONCE_LENGTH 18 +#define CLIENT_KEY "Client Key" +#define SERVER_KEY "Server Key" + +// EVP_MD_CTX_create() and EVP_MD_CTX_destroy() were renamed in OpenSSL 1.1.0 +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) +#define EVP_MD_CTX_new(ctx) EVP_MD_CTX_create(ctx) +#define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy(ctx) +#endif + +scram_session +*scram_create_session (const char *digest, const char *username, const char *password) +{ + scram_session *session; + const EVP_MD *md; +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) + OpenSSL_add_all_algorithms (); +#endif + md = EVP_get_digestbyname (digest); + + if (md == NULL) + { + // Unknown message digest + return NULL; + } + + session = g_new0 (scram_session, 1); + session->digest = md; + session->digest_size = EVP_MD_size (md); + session->username = g_strdup (username); + session->password = g_strdup (password); + return session; +} + +void +scram_free_session (scram_session *session) +{ + if (session == NULL) + { + return; + } + + g_free (session->username); + g_free (session->password); + g_free (session->client_nonce_b64); + g_free (session->client_first_message_bare); + g_free (session->salted_password); + g_free (session->auth_message); + g_free (session->error); + + g_free (session); +} + +static int +create_nonce (void *buffer, size_t length) +{ + return RAND_bytes (buffer, length); +} + +static int +create_SHA (scram_session *session, const unsigned char *input, size_t input_len, + unsigned char *output, unsigned int *output_len) +{ + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new (); + + if (!EVP_DigestInit_ex (md_ctx, session->digest, NULL)) + { + session->error = g_strdup ("Message digest initialization failed"); + EVP_MD_CTX_free (md_ctx); + return SCRAM_ERROR; + } + + if (!EVP_DigestUpdate (md_ctx, input, input_len)) + { + session->error = g_strdup ("Message digest update failed"); + EVP_MD_CTX_free (md_ctx); + return SCRAM_ERROR; + } + + if (!EVP_DigestFinal_ex (md_ctx, output, output_len)) + { + session->error = g_strdup ("Message digest finalization failed"); + EVP_MD_CTX_free (md_ctx); + return SCRAM_ERROR; + } + + EVP_MD_CTX_free (md_ctx); + return SCRAM_IN_PROGRESS; +} + +static scram_status +process_client_first (scram_session *session, char **output, size_t *output_len) +{ + char nonce[NONCE_LENGTH]; + + if (!create_nonce (nonce, NONCE_LENGTH)) + { + session->error = g_strdup ("Could not create client nonce"); + return SCRAM_ERROR; + } + + session->client_nonce_b64 = g_base64_encode ((guchar *) nonce, NONCE_LENGTH); + *output = g_strdup_printf ("n,,n=%s,r=%s", session->username, session->client_nonce_b64); + *output_len = strlen (*output); + session->client_first_message_bare = g_strdup (*output + 3); + session->step++; + return SCRAM_IN_PROGRESS; +} + +static scram_status +process_server_first (scram_session *session, const char *data, char **output, + size_t *output_len) +{ + char **params, *client_final_message_without_proof, *salt, *server_nonce_b64, + *client_proof_b64; + unsigned char *client_key, stored_key[EVP_MAX_MD_SIZE], *client_signature, *client_proof; + unsigned int i, param_count, iteration_count, client_key_len, stored_key_len; + gsize salt_len = 0; + size_t client_nonce_len; + + params = g_strsplit (data, ",", -1); + param_count = g_strv_length (params); + + if (param_count < 3) + { + session->error = g_strdup_printf ("Invalid server-first-message: %s", data); + g_strfreev (params); + return SCRAM_ERROR; + } + + server_nonce_b64 = NULL; + salt = NULL; + iteration_count = 0; + + for (i = 0; i < param_count; i++) + { + if (!strncmp (params[i], "r=", 2)) + { + server_nonce_b64 = g_strdup (params[i] + 2); + } + else if (!strncmp (params[i], "s=", 2)) + { + salt = g_strdup (params[i] + 2); + } + else if (!strncmp (params[i], "i=", 2)) + { + iteration_count = strtoul (params[i] + 2, NULL, 10); + } + } + + g_strfreev (params); + + if (server_nonce_b64 == NULL || *server_nonce_b64 == '\0' || salt == NULL || + *salt == '\0' || iteration_count == 0) + { + session->error = g_strdup_printf ("Invalid server-first-message: %s", data); + return SCRAM_ERROR; + } + + client_nonce_len = strlen (session->client_nonce_b64); + + // The server can append his nonce to the client's nonce + if (strlen (server_nonce_b64) < client_nonce_len || + strncmp (server_nonce_b64, session->client_nonce_b64, client_nonce_len)) + { + session->error = g_strdup_printf ("Invalid server nonce: %s", server_nonce_b64); + return SCRAM_ERROR; + } + + g_base64_decode_inplace ((gchar *) salt, &salt_len); + + // SaltedPassword := Hi(Normalize(password), salt, i) + session->salted_password = g_malloc (session->digest_size); + + PKCS5_PBKDF2_HMAC (session->password, strlen (session->password), (unsigned char *) salt, + salt_len, iteration_count, session->digest, session->digest_size, + session->salted_password); + + // AuthMessage := client-first-message-bare + "," + + // server-first-message + "," + + // client-final-message-without-proof + client_final_message_without_proof = g_strdup_printf ("c=biws,r=%s", server_nonce_b64); + + session->auth_message = g_strdup_printf ("%s,%s,%s", session->client_first_message_bare, + data, client_final_message_without_proof); + + // ClientKey := HMAC(SaltedPassword, "Client Key") + client_key = g_malloc0 (session->digest_size); + + HMAC (session->digest, session->salted_password, session->digest_size, + (unsigned char *) CLIENT_KEY, strlen (CLIENT_KEY), client_key, &client_key_len); + + // StoredKey := H(ClientKey) + if (!create_SHA (session, client_key, session->digest_size, stored_key, &stored_key_len)) + { + return SCRAM_ERROR; + } + + // ClientSignature := HMAC(StoredKey, AuthMessage) + client_signature = g_malloc0 (session->digest_size); + HMAC (session->digest, stored_key, stored_key_len, (unsigned char *) session->auth_message, + strlen ((char *) session->auth_message), client_signature, NULL); + + // ClientProof := ClientKey XOR ClientSignature + client_proof = g_malloc0 (client_key_len); + + for (i = 0; i < client_key_len; i++) + { + client_proof[i] = client_key[i] ^ client_signature[i]; + } + + client_proof_b64 = g_base64_encode ((guchar *) client_proof, client_key_len); + + *output = g_strdup_printf ("%s,p=%s", client_final_message_without_proof, client_proof_b64); + *output_len = strlen (*output); + + g_free (server_nonce_b64); + g_free (client_final_message_without_proof); + g_free (salt); + g_free (client_signature); + g_free (client_proof); + + session->step++; + return SCRAM_IN_PROGRESS; +} + +static scram_status +process_server_final (scram_session *session, const char *data) +{ + char *verifier; + unsigned char *server_key, *server_signature; + unsigned int server_key_len = 0, server_signature_len = 0; + gsize verifier_len = 0; + + if (strlen (data) < 3 || (data[0] != 'v' && data[1] != '=')) + { + return SCRAM_ERROR; + } + + verifier = g_strdup (data + 2); + g_base64_decode_inplace (verifier, &verifier_len); + + // ServerKey := HMAC(SaltedPassword, "Server Key") + server_key = g_malloc0 (session->digest_size); + HMAC (session->digest, session->salted_password, session->digest_size, + (unsigned char *) SERVER_KEY, strlen (SERVER_KEY), server_key, &server_key_len); + + // ServerSignature := HMAC(ServerKey, AuthMessage) + server_signature = g_malloc0 (session->digest_size); + HMAC (session->digest, server_key, session->digest_size, + (unsigned char *) session->auth_message, strlen ((char *) session->auth_message), + server_signature, &server_signature_len); + + if (verifier_len == server_signature_len && + memcmp (verifier, server_signature, verifier_len) == 0) + { + g_free (verifier); + g_free (server_key); + g_free (server_signature); + return SCRAM_SUCCESS; + } + else + { + g_free (verifier); + g_free (server_key); + g_free (server_signature); + return SCRAM_ERROR; + } +} + +scram_status +scram_process (scram_session *session, const char *input, char **output, size_t *output_len) +{ + scram_status status; + + switch (session->step) + { + case 0: + status = process_client_first (session, output, output_len); + break; + case 1: + status = process_server_first (session, input, output, output_len); + break; + case 2: + status = process_server_final (session, input); + break; + default: + *output = NULL; + *output_len = 0; + status = SCRAM_ERROR; + break; + } + + return status; +} + +#endif \ No newline at end of file diff --git a/src/common/scram.h b/src/common/scram.h new file mode 100644 index 00000000..d8f1429c --- /dev/null +++ b/src/common/scram.h @@ -0,0 +1,51 @@ +/* HexChat + * Copyright (C) 2023 Patrick Okraku + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef HEXCHAT_SCRAM_H +#define HEXCHAT_SCRAM_H + +#include "config.h" +#ifdef USE_OPENSSL +#include + +typedef struct +{ + const EVP_MD *digest; + size_t digest_size; + char *username; + char *password; + char *client_nonce_b64; + char *client_first_message_bare; + unsigned char *salted_password; + char *auth_message; + char *error; + int step; +} scram_session; + +typedef enum +{ + SCRAM_ERROR = 0, + SCRAM_IN_PROGRESS, + SCRAM_SUCCESS +} scram_status; + +scram_session *scram_create_session (const char *digset, const char *username, const char *password); +void scram_free_session (scram_session *session); +scram_status scram_process (scram_session *session, const char *input, char **output, size_t *output_len); + +#endif +#endif \ No newline at end of file diff --git a/src/common/server.c b/src/common/server.c index e14da237..97f8425d 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1765,7 +1765,9 @@ server_set_defaults (server *serv) g_free (serv->chanmodes); g_free (serv->nick_prefixes); g_free (serv->nick_modes); - +#ifdef USE_OPENSSL + g_clear_pointer (&serv->scram_session, scram_free_session); +#endif serv->chantypes = g_strdup ("#&!+"); serv->chanmodes = g_strdup ("beI,k,l"); serv->nick_prefixes = g_strdup ("@%+"); @@ -1937,6 +1939,8 @@ server_free (server *serv) #ifdef USE_OPENSSL if (serv->ctx) _SSL_context_free (serv->ctx); + + g_clear_pointer (&serv->scram_session, scram_free_session); #endif fe_server_callback (serv); diff --git a/src/common/servlist.h b/src/common/servlist.h index ec885fef..c3d158b2 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -79,6 +79,9 @@ extern GSList *network_list; #define LOGIN_CHALLENGEAUTH 8 #define LOGIN_CUSTOM 9 #define LOGIN_SASLEXTERNAL 10 +#define LOGIN_SASL_SCRAM_SHA_1 11 +#define LOGIN_SASL_SCRAM_SHA_256 12 +#define LOGIN_SASL_SCRAM_SHA_512 13 #define CHALLENGEAUTH_ALGO "HMAC-SHA-256" #define CHALLENGEAUTH_NICK "Q@CServe.quakenet.org" diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index edcd4609..0e5e108b 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -128,6 +128,9 @@ static int login_types_conf[] = LOGIN_SASL, #ifdef USE_OPENSSL LOGIN_SASLEXTERNAL, + LOGIN_SASL_SCRAM_SHA_1, + LOGIN_SASL_SCRAM_SHA_256, + LOGIN_SASL_SCRAM_SHA_512, #endif LOGIN_PASS, LOGIN_MSG_NICKSERV, @@ -146,9 +149,12 @@ static int login_types_conf[] = static const char *login_types[]= { "Default", - "SASL (username + password)", + "SASL PLAIN (username + password)", #ifdef USE_OPENSSL "SASL EXTERNAL (cert)", + "SASL SCRAM-SHA-1", + "SASL SCRAM-SHA-256", + "SASL SCRAM-SHA-512", #endif "Server password (/PASS password)", "NickServ (/MSG NickServ + password)", -- cgit 1.4.1 From c82ad321713dbbe77ff861dc2fa29954c214000c Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Mon, 6 Nov 2023 15:04:15 +0100 Subject: SASL SCRAM: Apply changes from code review --- src/common/inbound.c | 2 +- src/common/scram.c | 14 ++++++++++++-- src/common/scram.h | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 9b38f7c7..e8cfd0b5 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1985,7 +1985,7 @@ scram_authenticate (server *serv, const char *data, const char *digest, if (serv->scram_session == NULL) { - serv->scram_session = scram_create_session (digest, user, password); + serv->scram_session = scram_session_create (digest, user, password); if (serv->scram_session == NULL) { diff --git a/src/common/scram.c b/src/common/scram.c index 529abd5d..b9f2beb0 100644 --- a/src/common/scram.c +++ b/src/common/scram.c @@ -35,7 +35,7 @@ #endif scram_session -*scram_create_session (const char *digest, const char *username, const char *password) +*scram_session_create (const char *digest, const char *username, const char *password) { scram_session *session; const EVP_MD *md; @@ -162,10 +162,12 @@ process_server_first (scram_session *session, const char *data, char **output, { if (!strncmp (params[i], "r=", 2)) { + g_free (server_nonce_b64); server_nonce_b64 = g_strdup (params[i] + 2); } else if (!strncmp (params[i], "s=", 2)) { + g_free (salt); salt = g_strdup (params[i] + 2); } else if (!strncmp (params[i], "i=", 2)) @@ -180,6 +182,8 @@ process_server_first (scram_session *session, const char *data, char **output, *salt == '\0' || iteration_count == 0) { session->error = g_strdup_printf ("Invalid server-first-message: %s", data); + g_free (server_nonce_b64); + g_free (salt); return SCRAM_ERROR; } @@ -219,6 +223,10 @@ process_server_first (scram_session *session, const char *data, char **output, // StoredKey := H(ClientKey) if (!create_SHA (session, client_key, session->digest_size, stored_key, &stored_key_len)) { + g_free (client_final_message_without_proof); + g_free (server_nonce_b64); + g_free (salt); + g_free (client_key); return SCRAM_ERROR; } @@ -241,10 +249,12 @@ process_server_first (scram_session *session, const char *data, char **output, *output_len = strlen (*output); g_free (server_nonce_b64); - g_free (client_final_message_without_proof); g_free (salt); + g_free (client_final_message_without_proof); + g_free (client_key); g_free (client_signature); g_free (client_proof); + g_free (client_proof_b64); session->step++; return SCRAM_IN_PROGRESS; diff --git a/src/common/scram.h b/src/common/scram.h index d8f1429c..68672448 100644 --- a/src/common/scram.h +++ b/src/common/scram.h @@ -43,7 +43,7 @@ typedef enum SCRAM_SUCCESS } scram_status; -scram_session *scram_create_session (const char *digset, const char *username, const char *password); +scram_session *scram_session_create (const char *digset, const char *username, const char *password); void scram_free_session (scram_session *session); scram_status scram_process (scram_session *session, const char *input, char **output, size_t *output_len); -- cgit 1.4.1 From 681a88d6df2ad67e3d590fada15322b1b3ee08af Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Sun, 12 Nov 2023 12:45:08 +0100 Subject: SASL SCRAM: renamed scram_free_session to scram_session_free --- src/common/inbound.c | 6 +++--- src/common/scram.c | 2 +- src/common/scram.h | 2 +- src/common/server.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index e8cfd0b5..fdee2ecc 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -2012,7 +2012,7 @@ scram_authenticate (server *serv, const char *data, const char *digest, { // Authentication succeeded tcp_sendf (serv, "AUTHENTICATE +\r\n"); - g_clear_pointer (&serv->scram_session, scram_free_session); + g_clear_pointer (&serv->scram_session, scram_session_free); } else if (status == SCRAM_ERROR) { @@ -2025,7 +2025,7 @@ scram_authenticate (server *serv, const char *data, const char *digest, g_info ("SASL SCRAM authentication failed: %s", serv->scram_session->error); } - g_clear_pointer (&serv->scram_session, scram_free_session); + g_clear_pointer (&serv->scram_session, scram_session_free); } } #endif @@ -2076,7 +2076,7 @@ void inbound_sasl_error (server *serv) { #ifdef USE_OPENSSL - g_clear_pointer (&serv->scram_session, scram_free_session); + g_clear_pointer (&serv->scram_session, scram_session_free); #endif /* Just abort, not much we can do */ tcp_sendf (serv, "AUTHENTICATE *\r\n"); diff --git a/src/common/scram.c b/src/common/scram.c index b9f2beb0..b39199de 100644 --- a/src/common/scram.c +++ b/src/common/scram.c @@ -59,7 +59,7 @@ scram_session } void -scram_free_session (scram_session *session) +scram_session_free (scram_session *session) { if (session == NULL) { diff --git a/src/common/scram.h b/src/common/scram.h index 68672448..ffe22037 100644 --- a/src/common/scram.h +++ b/src/common/scram.h @@ -44,7 +44,7 @@ typedef enum } scram_status; scram_session *scram_session_create (const char *digset, const char *username, const char *password); -void scram_free_session (scram_session *session); +void scram_session_free (scram_session *session); scram_status scram_process (scram_session *session, const char *input, char **output, size_t *output_len); #endif diff --git a/src/common/server.c b/src/common/server.c index 97f8425d..c78ce900 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -1766,7 +1766,7 @@ server_set_defaults (server *serv) g_free (serv->nick_prefixes); g_free (serv->nick_modes); #ifdef USE_OPENSSL - g_clear_pointer (&serv->scram_session, scram_free_session); + g_clear_pointer (&serv->scram_session, scram_session_free); #endif serv->chantypes = g_strdup ("#&!+"); serv->chanmodes = g_strdup ("beI,k,l"); @@ -1940,7 +1940,7 @@ server_free (server *serv) if (serv->ctx) _SSL_context_free (serv->ctx); - g_clear_pointer (&serv->scram_session, scram_free_session); + g_clear_pointer (&serv->scram_session, scram_session_free); #endif fe_server_callback (serv); -- cgit 1.4.1 From 00b297524d7f5df07ae5d0827bc0eb4018651765 Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Sat, 30 Dec 2023 11:09:34 +0100 Subject: SASL SCRAM: create_nonce: changed data type --- src/common/scram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scram.c b/src/common/scram.c index b39199de..f572d84d 100644 --- a/src/common/scram.c +++ b/src/common/scram.c @@ -78,7 +78,7 @@ scram_session_free (scram_session *session) } static int -create_nonce (void *buffer, size_t length) +create_nonce (char *buffer, size_t length) { return RAND_bytes (buffer, length); } -- cgit 1.4.1 From 0c4878554323e6cd9a60b3dd5b19ffccb40dfb63 Mon Sep 17 00:00:00 2001 From: Patrick Okraku Date: Sat, 30 Dec 2023 13:33:36 +0100 Subject: SASL SCRAM: create_nonce: changed data type --- src/common/scram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scram.c b/src/common/scram.c index f572d84d..b39199de 100644 --- a/src/common/scram.c +++ b/src/common/scram.c @@ -78,7 +78,7 @@ scram_session_free (scram_session *session) } static int -create_nonce (char *buffer, size_t length) +create_nonce (void *buffer, size_t length) { return RAND_bytes (buffer, length); } -- cgit 1.4.1 From 180ce9f4fde4f87150b69e0cf40873226dbb9455 Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Sun, 28 Jan 2024 19:33:45 -0800 Subject: Change various types to the correct signedness to avoid warnings. Also cast the check of "inet_addr" to guint32. The POSIX declaration of this function returns in_addr_t which is the same as uint32_t. Windows does not define this type and instead uses unsigned long. --- plugins/fishlim/fish.c | 3 ++- plugins/fishlim/tests/tests.c | 2 +- src/common/dbus/dbus-client.c | 2 +- src/common/modes.c | 2 +- src/common/outbound.c | 2 +- src/common/url.c | 2 +- src/common/util.c | 2 +- src/fe-gtk/xtext.c | 3 ++- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/fishlim/fish.c b/plugins/fishlim/fish.c index 7fe7e287..0b24ed48 100644 --- a/plugins/fishlim/fish.c +++ b/plugins/fishlim/fish.c @@ -145,7 +145,8 @@ void fish_deinit(void) */ char *fish_base64_encode(const char *message, size_t message_len) { BF_LONG left = 0, right = 0; - int i, j; + int i; + size_t j; char *encoded = NULL; char *end = NULL; char *msg = NULL; diff --git a/plugins/fishlim/tests/tests.c b/plugins/fishlim/tests/tests.c index 12b10d1d..553816d3 100644 --- a/plugins/fishlim/tests/tests.c +++ b/plugins/fishlim/tests/tests.c @@ -36,7 +36,7 @@ static void random_string(char *out, size_t len) { GRand *rand = NULL; - int i = 0; + size_t i = 0; rand = g_rand_new(); for (i = 0; i < len; ++i) { diff --git a/src/common/dbus/dbus-client.c b/src/common/dbus/dbus-client.c index 8b40dd24..e70a49a9 100644 --- a/src/common/dbus/dbus-client.c +++ b/src/common/dbus/dbus-client.c @@ -67,7 +67,7 @@ hexchat_remote (void) gboolean hexchat_running; GError *error = NULL; char *command = NULL; - int i; + guint i; /* if there is nothing to do, return now. */ if (!arg_existing || !(arg_url || arg_urls || arg_command)) { diff --git a/src/common/modes.c b/src/common/modes.c index d8fd75aa..1ff309bd 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -680,7 +680,7 @@ handle_mode (server * serv, char *word[], char *word_eol[], int len; size_t arg; size_t i, num_args; - int num_modes; + size_t num_modes; size_t offset = 3; int all_modes_have_args = FALSE; int using_front_tab = FALSE; diff --git a/src/common/outbound.c b/src/common/outbound.c index c82e23bd..b8153502 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -468,7 +468,7 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop) type = prefs.hex_irc_ban_type; buf[0] = 0; - if (inet_addr (fullhost) != -1) /* "fullhost" is really a IP number */ + if (inet_addr (fullhost) != (guint32) -1) /* "fullhost" is really a IP number */ { lastdot = strrchr (fullhost, '.'); if (!lastdot) diff --git a/src/common/url.c b/src/common/url.c index 6a1d09e8..ae85ae44 100644 --- a/src/common/url.c +++ b/src/common/url.c @@ -331,7 +331,7 @@ url_check_line (char *buf) GRegex *re(void); GMatchInfo *gmi; char *po = buf; - int i; + size_t i; /* Skip over message prefix */ if (*po == ':') diff --git a/src/common/util.c b/src/common/util.c index f06074fc..bd920cae 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -988,7 +988,7 @@ void country_search (char *pattern, void *ud, void (*print)(void *, char *, ...)) { const domain_t *dom; - int i; + size_t i; for (i = 0; i < sizeof (domain) / sizeof (domain_t); i++) { diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 08a5110a..be978f22 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -170,7 +170,8 @@ xtext_pango_attr (PangoAttribute *attr) static void xtext_pango_init (GtkXText *xtext) { - int i, j; + size_t i; + int j; char buf[2] = "\000"; if (attr_lists[0]) -- cgit 1.4.1 From 434a210ef79241cd650dd074b66a9ce87e8450a1 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Wed, 7 Feb 2024 06:01:12 -0600 Subject: 2.16.2 --- data/misc/io.github.Hexchat.appdata.xml.in | 12 ++++++++++++ meson.build | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/data/misc/io.github.Hexchat.appdata.xml.in b/data/misc/io.github.Hexchat.appdata.xml.in index d75cc1cc..6e3cf2e6 100644 --- a/data/misc/io.github.Hexchat.appdata.xml.in +++ b/data/misc/io.github.Hexchat.appdata.xml.in @@ -27,6 +27,18 @@ hexchat.desktop + + +

This is a minor release with small improvements and fixes:

+
    +
  • Add support for SCRAM SASL mechanisms
  • +
  • Add option to hide nick from window title
  • +
  • Change SERVER command to default to TLS, adding an "-insecure" argument
  • +
  • Increase max server password length to 1024
  • +
  • Fix detecting some URLS causing a crash
  • +
+
+

This is a minor release with mostly bug-fixes:

diff --git a/meson.build b/meson.build index f187c4b2..2f8fb3f2 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('hexchat', 'c', - version: '2.16.1', + version: '2.16.2', meson_version: '>= 0.47.0', default_options: [ 'c_std=gnu89', -- cgit 1.4.1 From 70069cd50eb07e8a40ac9b0efbb83fcb91a78b99 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 9 Feb 2024 14:20:48 -0600 Subject: appdata: Fix release date --- data/misc/io.github.Hexchat.appdata.xml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/misc/io.github.Hexchat.appdata.xml.in b/data/misc/io.github.Hexchat.appdata.xml.in index 6e3cf2e6..0d67a0b6 100644 --- a/data/misc/io.github.Hexchat.appdata.xml.in +++ b/data/misc/io.github.Hexchat.appdata.xml.in @@ -27,7 +27,7 @@ hexchat.desktop - +

This is a minor release with small improvements and fixes:

    -- cgit 1.4.1 From cc60ad275a56126904df0b5e37cfd20db22cb359 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Fri, 9 Feb 2024 18:29:15 -0600 Subject: Replace hexchat.net links --- .github/workflows/windows-build.yml | 10 +++++----- plugins/upd/upd.c | 2 +- win32/installer/hexchat.iss.tt | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 3ba01e8b..9ad55fac 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -31,19 +31,19 @@ jobs: Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe & deps\innosetup-unicode.exe /VERYSILENT | Out-Null - Invoke-WebRequest https://dl.hexchat.net/misc/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe & deps\idpsetup.exe /VERYSILENT - Invoke-WebRequest https://dl.hexchat.net/gtk/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z & 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk - Invoke-WebRequest https://dl.hexchat.net/gtk-win32/gendef-20111031.7z -OutFile deps\gendef.7z + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/gendef-20111031.7z-OutFile deps\gendef.7z & 7z.exe x deps\gendef.7z -oC:\gtk-build - Invoke-WebRequest https://dl.hexchat.net/gtk-win32/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z & 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle - Invoke-WebRequest https://dl.hexchat.net/misc/perl/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z & 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }} New-Item -Path "c:\gtk-build" -Name "python-3.8" -ItemType "Directory" diff --git a/plugins/upd/upd.c b/plugins/upd/upd.c index c9011c04..2a938596 100644 --- a/plugins/upd/upd.c +++ b/plugins/upd/upd.c @@ -24,7 +24,7 @@ #include "hexchat-plugin.h" -#define APPCAST_URL "https://dl.hexchat.net/appcast.xml" +#define APPCAST_URL "https://hexchat.github.io/appcast.xml" static hexchat_plugin *ph; /* plugin handle */ static char name[] = "Update Checker"; diff --git a/win32/installer/hexchat.iss.tt b/win32/installer/hexchat.iss.tt index 1b7c3209..8337258f 100644 --- a/win32/installer/hexchat.iss.tt +++ b/win32/installer/hexchat.iss.tt @@ -295,18 +295,18 @@ begin begin #if APPARCH == "x64" - REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x64.exe'; - REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x64.exe'; - PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x64.msi'; + REDIST := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/vcredist_2015_x64.exe'; + REDIST_2013 := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/vcredist_2013_x64.exe'; + PERL := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/Perl.5.20.0.x64.msi'; PY3 := 'https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe'; #else - REDIST := 'https://dl.hexchat.net/misc/vcredist_2015_x86.exe'; - REDIST_2013 := 'https://dl.hexchat.net/misc/vcredist_2013_x86.exe'; - PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x86.msi'; + REDIST := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/vcredist_2015_x86.exe'; + REDIST_2013 := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/vcredist_2013_x86.exe'; + PERL := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/Perl.5.20.0.x86.msi'; PY3 := 'https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe'; #endif - DOTNET := 'https://dl.hexchat.net/misc/dotnet_40.exe'; - SPELL := 'https://dl.hexchat.net/hexchat/HexChat%20Spelling%20Dictionaries%20r2.exe'; + DOTNET := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/dotnet_40.exe'; + SPELL := 'https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/HexChat.Spelling.Dictionaries.r2.exe'; if not CheckVCInstall() then idpAddFile(REDIST, ExpandConstant('{tmp}\vcredist.exe')); -- cgit 1.4.1 From b544ac3350e85d4cc41fe3414cbdb82d75ce5d7a Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Fri, 9 Feb 2024 18:32:55 -0600 Subject: CI: Fix typo --- .github/workflows/windows-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 9ad55fac..dbbf6499 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -37,7 +37,7 @@ jobs: Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z & 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk - Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/gendef-20111031.7z-OutFile deps\gendef.7z + Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/gendef-20111031.7z -OutFile deps\gendef.7z & 7z.exe x deps\gendef.7z -oC:\gtk-build Invoke-WebRequest https://github.com/hexchat/gvsbuild/releases/download/hexchat-2.16.2/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z -- cgit 1.4.1