mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-18 20:39:25 +00:00
Compare commits
3 Commits
fishlim-ma
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 944d0f5a70 | |||
|
|
8220e60257 | ||
| 5833f8a3d8 |
102
packaging/fedora/zoitechat.spec
Normal file
102
packaging/fedora/zoitechat.spec
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
Name: zoitechat
|
||||||
|
Version: 2.18.1
|
||||||
|
Release: %autorelease
|
||||||
|
Summary: HexChat-based IRC client
|
||||||
|
License: GPL-2.0-or-later WITH cryptsetup-OpenSSL-exception
|
||||||
|
URL: https://github.com/ZoiteChat/zoitechat
|
||||||
|
Source0: %{url}/archive/refs/tags/%{name}-%{version}.tar.gz
|
||||||
|
|
||||||
|
BuildRequires: desktop-file-utils
|
||||||
|
BuildRequires: gcc
|
||||||
|
BuildRequires: gettext
|
||||||
|
BuildRequires: libappstream-glib
|
||||||
|
BuildRequires: meson >= 0.55.0
|
||||||
|
BuildRequires: perl
|
||||||
|
BuildRequires: perl-devel
|
||||||
|
BuildRequires: python3
|
||||||
|
BuildRequires: python3-cffi
|
||||||
|
BuildRequires: publicsuffix-list
|
||||||
|
BuildRequires: xorg-x11-server-Xvfb
|
||||||
|
BuildRequires: pkgconfig(ayatana-appindicator3-0.1)
|
||||||
|
BuildRequires: pkgconfig(dbus-glib-1)
|
||||||
|
BuildRequires: pkgconfig(gio-2.0) >= 2.36.0
|
||||||
|
BuildRequires: pkgconfig(gmodule-2.0)
|
||||||
|
BuildRequires: pkgconfig(gtk+-3.0) >= 3.22
|
||||||
|
BuildRequires: pkgconfig(iso-codes)
|
||||||
|
BuildRequires: pkgconfig(libarchive)
|
||||||
|
BuildRequires: pkgconfig(libcanberra) >= 0.22
|
||||||
|
BuildRequires: pkgconfig(libpci)
|
||||||
|
BuildRequires: pkgconfig(lua)
|
||||||
|
BuildRequires: pkgconfig(openssl) >= 0.9.8
|
||||||
|
BuildRequires: pkgconfig(python3)
|
||||||
|
|
||||||
|
Requires: hicolor-icon-theme
|
||||||
|
Requires: iso-codes
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Summary: Development files for ZoiteChat plugins
|
||||||
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||||
|
|
||||||
|
%description devel
|
||||||
|
Development files for building ZoiteChat plugins.
|
||||||
|
|
||||||
|
%description
|
||||||
|
ZoiteChat is a HexChat-based IRC client for Windows and UNIX-like operating
|
||||||
|
systems.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -C
|
||||||
|
|
||||||
|
%build
|
||||||
|
%meson \
|
||||||
|
-Dtext-frontend=false \
|
||||||
|
-Dwith-checksum=true \
|
||||||
|
-Dwith-fishlim=true \
|
||||||
|
-Dwith-lua=lua \
|
||||||
|
-Dwith-perl=perl \
|
||||||
|
-Dwith-python=python3 \
|
||||||
|
-Dwith-sysinfo=true \
|
||||||
|
-Dinstall-appdata=true \
|
||||||
|
-Dinstall-plugin-metainfo=true
|
||||||
|
%meson_build
|
||||||
|
|
||||||
|
%install
|
||||||
|
%meson_install
|
||||||
|
%find_lang %{name}
|
||||||
|
|
||||||
|
%check
|
||||||
|
desktop-file-validate %{buildroot}%{_datadir}/applications/net.zoite.Zoitechat.desktop
|
||||||
|
|
||||||
|
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/net.zoite.Zoitechat.appdata.xml
|
||||||
|
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/net.zoite.Zoitechat*.metainfo.xml
|
||||||
|
|
||||||
|
xvfb-run -a /usr/bin/meson test -C %{_vpath_builddir} --num-processes %{_smp_build_ncpus} --print-errorlogs \
|
||||||
|
"Theme Manager Dispatch Routing Tests" \
|
||||||
|
"Validate net.zoite.Zoitechat.desktop" \
|
||||||
|
"Theme GTK3 Settings Tests" \
|
||||||
|
"Validate translations" \
|
||||||
|
"Fishlim Tests"
|
||||||
|
|
||||||
|
%files -f %{name}.lang
|
||||||
|
%license COPYING
|
||||||
|
%doc readme.md troubleshooting.md
|
||||||
|
%{_bindir}/zoitechat
|
||||||
|
%{_datadir}/applications/net.zoite.Zoitechat.desktop
|
||||||
|
%{_datadir}/dbus-1/services/org.zoitechat.service.service
|
||||||
|
%{_datadir}/icons/hicolor/48x48/apps/net.zoite.Zoitechat.png
|
||||||
|
%{_datadir}/icons/hicolor/scalable/apps/net.zoite.Zoitechat.svg
|
||||||
|
%{_datadir}/metainfo/net.zoite.Zoitechat.appdata.xml
|
||||||
|
%{_datadir}/metainfo/net.zoite.Zoitechat*.metainfo.xml
|
||||||
|
%dir %{_libdir}/zoitechat
|
||||||
|
%dir %{_libdir}/zoitechat/plugins
|
||||||
|
%dir %{_libdir}/zoitechat/python
|
||||||
|
%{_libdir}/zoitechat/plugins/*.so
|
||||||
|
%{_libdir}/zoitechat/python/*.py
|
||||||
|
%{_mandir}/man1/zoitechat.1*
|
||||||
|
|
||||||
|
%files devel
|
||||||
|
%{_includedir}/zoitechat-plugin.h
|
||||||
|
%{_libdir}/pkgconfig/zoitechat-plugin.pc
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
%autochangelog
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
|
||||||
|
|||||||
@@ -194,18 +194,6 @@ static gboolean keyfile_save_to_file (GKeyFile *keyfile, char *filename) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
gchar **keystore_get_targets(gsize *length) {
|
|
||||||
GKeyFile *keyfile;
|
|
||||||
gchar **groups;
|
|
||||||
|
|
||||||
keyfile = getConfigFile();
|
|
||||||
groups = g_key_file_get_groups(keyfile, length);
|
|
||||||
g_key_file_free(keyfile);
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the key store file to disk.
|
* Writes the key store file to disk.
|
||||||
*/
|
*/
|
||||||
@@ -229,7 +217,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
|||||||
/**
|
/**
|
||||||
* Sets a key in the key store file.
|
* Sets a key in the key store file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode) {
|
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode) {
|
||||||
const char *password;
|
const char *password;
|
||||||
char *encrypted;
|
char *encrypted;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
char *keystore_get_key(const char *nick, enum fish_mode *mode);
|
char *keystore_get_key(const char *nick, enum fish_mode *mode);
|
||||||
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode);
|
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode);
|
||||||
gboolean keystore_delete_nick(const char *nick);
|
gboolean keystore_delete_nick(const char *nick);
|
||||||
gchar **keystore_get_targets(gsize *length);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ fishlim_sources = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
shared_module('fishlim', fishlim_sources,
|
shared_module('fishlim', fishlim_sources,
|
||||||
dependencies: [libgio_dep, gtk_dep, zoitechat_plugin_dep, libssl_dep],
|
dependencies: [libgio_dep, zoitechat_plugin_dep, libssl_dep],
|
||||||
c_args: ['-DOPENSSL_API_COMPAT=0x10100000L'],
|
c_args: ['-DOPENSSL_API_COMPAT=0x10100000L'],
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: plugindir,
|
install_dir: plugindir,
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "zoitechat-plugin.h"
|
#include "zoitechat-plugin.h"
|
||||||
@@ -45,7 +44,7 @@ static const char plugin_version[] = "1.0.0";
|
|||||||
|
|
||||||
static const char usage_setkey[] = "Usage: SETKEY [<nick or #channel>] [<mode>:]<password>, sets the key for a channel or nick. Modes: ECB, CBC";
|
static const char usage_setkey[] = "Usage: SETKEY [<nick or #channel>] [<mode>:]<password>, sets the key for a channel or nick. Modes: ECB, CBC";
|
||||||
static const char usage_delkey[] = "Usage: DELKEY [<nick or #channel>], deletes the key for a channel or nick";
|
static const char usage_delkey[] = "Usage: DELKEY [<nick or #channel>], deletes the key for a channel or nick";
|
||||||
static const char usage_keyx[] = "Usage: KEYX [<nick>] [ECB|CBC], performs DH1080 key-exchange with <nick>";
|
static const char usage_keyx[] = "Usage: KEYX [<nick>], performs DH1080 key-exchange with <nick>";
|
||||||
static const char usage_topic[] = "Usage: TOPIC+ <topic>, sets a new encrypted topic for the current channel";
|
static const char usage_topic[] = "Usage: TOPIC+ <topic>, sets a new encrypted topic for the current channel";
|
||||||
static const char usage_notice[] = "Usage: NOTICE+ <nick or #channel> <notice>";
|
static const char usage_notice[] = "Usage: NOTICE+ <nick or #channel> <notice>";
|
||||||
static const char usage_msg[] = "Usage: MSG+ <nick or #channel> <message>";
|
static const char usage_msg[] = "Usage: MSG+ <nick or #channel> <message>";
|
||||||
@@ -53,13 +52,6 @@ static const char usage_msg[] = "Usage: MSG+ <nick or #channel> <message>";
|
|||||||
|
|
||||||
static zoitechat_plugin *ph;
|
static zoitechat_plugin *ph;
|
||||||
static GHashTable *pending_exchanges;
|
static GHashTable *pending_exchanges;
|
||||||
static GtkWidget *fishlim_dialog;
|
|
||||||
static GtkWidget *fishlim_target_entry;
|
|
||||||
static GtkWidget *fishlim_key_entry;
|
|
||||||
static GtkWidget *fishlim_mode_combo;
|
|
||||||
static GtkWidget *fishlim_status_label;
|
|
||||||
static GtkListStore *fishlim_store;
|
|
||||||
static GtkWidget *fishlim_view;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -463,314 +455,6 @@ cleanup:
|
|||||||
return ZOITECHAT_EAT_ALL;
|
return ZOITECHAT_EAT_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *fishlim_gui_target(void) {
|
|
||||||
const char *target;
|
|
||||||
|
|
||||||
target = gtk_entry_get_text(GTK_ENTRY(fishlim_target_entry));
|
|
||||||
if (target && *target)
|
|
||||||
return target;
|
|
||||||
|
|
||||||
return zoitechat_get_info(ph, "channel");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_refresh(void) {
|
|
||||||
GtkTreeIter iter;
|
|
||||||
gchar **targets;
|
|
||||||
gsize length, i;
|
|
||||||
const char *target;
|
|
||||||
char *key;
|
|
||||||
enum fish_mode mode;
|
|
||||||
|
|
||||||
if (!fishlim_dialog)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gtk_list_store_clear(fishlim_store);
|
|
||||||
targets = keystore_get_targets(&length);
|
|
||||||
|
|
||||||
for (i = 0; targets && i < length; i++) {
|
|
||||||
key = keystore_get_key(targets[i], &mode);
|
|
||||||
gtk_list_store_append(fishlim_store, &iter);
|
|
||||||
gtk_list_store_set(fishlim_store, &iter, 0, targets[i], 1, fish_modes[mode], 2, key ? "Stored" : "Unreadable", -1);
|
|
||||||
g_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_strfreev(targets);
|
|
||||||
|
|
||||||
target = fishlim_gui_target();
|
|
||||||
key = target ? keystore_get_key(target, &mode) : NULL;
|
|
||||||
|
|
||||||
if (key) {
|
|
||||||
char *text = g_strdup_printf("Key stored for %s (%s)", target, fish_modes[mode]);
|
|
||||||
gtk_label_set_text(GTK_LABEL(fishlim_status_label), text);
|
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(fishlim_mode_combo), mode == FISH_CBC_MODE ? 1 : 0);
|
|
||||||
g_free(text);
|
|
||||||
g_free(key);
|
|
||||||
} else if (target && *target) {
|
|
||||||
char *text = g_strdup_printf("No key for %s", target);
|
|
||||||
gtk_label_set_text(GTK_LABEL(fishlim_status_label), text);
|
|
||||||
g_free(text);
|
|
||||||
} else {
|
|
||||||
gtk_label_set_text(GTK_LABEL(fishlim_status_label), "No target selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_refresh_cb(GtkWidget *widget, gpointer data) {
|
|
||||||
fishlim_gui_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_send_channel_key(const char *channel, const char *mode, const char *key) {
|
|
||||||
GtkWidget *dialog, *content, *entry, *label;
|
|
||||||
char **users;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!channel || !*channel || irc_is_query(channel))
|
|
||||||
return;
|
|
||||||
|
|
||||||
dialog = gtk_dialog_new_with_buttons("Share Channel Key", GTK_WINDOW(fishlim_dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Skip", GTK_RESPONSE_CANCEL, "_Send", GTK_RESPONSE_OK, NULL);
|
|
||||||
content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
|
||||||
label = gtk_label_new("Send this channel key to users by private message. Enter users separated by commas.");
|
|
||||||
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
|
|
||||||
gtk_box_pack_start(GTK_BOX(content), label, FALSE, FALSE, 6);
|
|
||||||
entry = gtk_entry_new();
|
|
||||||
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "nick1, nick2, nick3");
|
|
||||||
gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
|
|
||||||
gtk_box_pack_start(GTK_BOX(content), entry, FALSE, FALSE, 6);
|
|
||||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
|
|
||||||
gtk_widget_show_all(dialog);
|
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
|
|
||||||
users = g_strsplit(gtk_entry_get_text(GTK_ENTRY(entry)), ",", -1);
|
|
||||||
for (i = 0; users && users[i]; i++) {
|
|
||||||
char *user = g_strstrip(users[i]);
|
|
||||||
if (*user)
|
|
||||||
zoitechat_commandf(ph, "msg %s Encrypted chat invite: join %s, open FiSHLiM Key Manager, add channel %s with %s key: %s. Key exchange is for private messages only.", user, channel, channel, mode, key);
|
|
||||||
}
|
|
||||||
g_strfreev(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_set(GtkWidget *widget, gpointer data) {
|
|
||||||
const char *target = fishlim_gui_target();
|
|
||||||
const char *key = gtk_entry_get_text(GTK_ENTRY(fishlim_key_entry));
|
|
||||||
const char *mode = gtk_combo_box_get_active(GTK_COMBO_BOX(fishlim_mode_combo)) == 1 ? "CBC" : "ECB";
|
|
||||||
|
|
||||||
if (!target || !*target || !key || !*key) {
|
|
||||||
zoitechat_printf(ph, "%s\n", usage_setkey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
zoitechat_commandf(ph, "SETKEY %s %s:%s", target, mode, key);
|
|
||||||
fishlim_gui_send_channel_key(target, mode, key);
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(fishlim_key_entry), "");
|
|
||||||
fishlim_gui_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean fishlim_gui_confirm_delete(const char *target) {
|
|
||||||
GtkWidget *dialog;
|
|
||||||
char *message;
|
|
||||||
gboolean confirmed;
|
|
||||||
|
|
||||||
message = g_strdup_printf("Delete the key for %s?", target);
|
|
||||||
dialog = gtk_message_dialog_new(GTK_WINDOW(fishlim_dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, "%s", message);
|
|
||||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "This cannot be undone.");
|
|
||||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "_Cancel", GTK_RESPONSE_CANCEL, "_Delete", GTK_RESPONSE_ACCEPT, NULL);
|
|
||||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
|
|
||||||
confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT;
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
g_free(message);
|
|
||||||
return confirmed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *fishlim_gui_selected_target(void) {
|
|
||||||
GtkTreeSelection *selection;
|
|
||||||
GtkTreeModel *model;
|
|
||||||
GtkTreeIter iter;
|
|
||||||
char *target = NULL;
|
|
||||||
|
|
||||||
if (!fishlim_view)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(fishlim_view));
|
|
||||||
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
|
||||||
gtk_tree_model_get(model, &iter, 0, &target, -1);
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_delete(GtkWidget *widget, gpointer data) {
|
|
||||||
char *selected = fishlim_gui_selected_target();
|
|
||||||
const char *target = selected ? selected : fishlim_gui_target();
|
|
||||||
|
|
||||||
if (!target || !*target) {
|
|
||||||
zoitechat_printf(ph, "%s\n", usage_delkey);
|
|
||||||
g_free(selected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fishlim_gui_confirm_delete(target)) {
|
|
||||||
zoitechat_commandf(ph, "DELKEY %s", target);
|
|
||||||
fishlim_gui_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *fishlim_gui_prompt_target(const char *title, const char *initial) {
|
|
||||||
GtkWidget *dialog, *content, *entry;
|
|
||||||
char *target = NULL;
|
|
||||||
|
|
||||||
dialog = gtk_dialog_new_with_buttons(title, GTK_WINDOW(fishlim_dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL);
|
|
||||||
content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
|
||||||
entry = gtk_entry_new();
|
|
||||||
if (initial && *initial)
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(entry), initial);
|
|
||||||
gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
|
|
||||||
gtk_box_pack_start(GTK_BOX(content), gtk_label_new("Private message user"), FALSE, FALSE, 6);
|
|
||||||
gtk_box_pack_start(GTK_BOX(content), entry, FALSE, FALSE, 6);
|
|
||||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
|
|
||||||
gtk_widget_show_all(dialog);
|
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
|
|
||||||
const char *text = gtk_entry_get_text(GTK_ENTRY(entry));
|
|
||||||
if (text && *text)
|
|
||||||
target = g_strdup(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_keyx(GtkWidget *widget, gpointer data) {
|
|
||||||
char *target;
|
|
||||||
const char *initial = fishlim_gui_target();
|
|
||||||
const char *mode = gtk_combo_box_get_active(GTK_COMBO_BOX(fishlim_mode_combo)) == 1 ? "CBC" : "ECB";
|
|
||||||
|
|
||||||
if (!initial || !*initial || !irc_is_query(initial))
|
|
||||||
initial = NULL;
|
|
||||||
|
|
||||||
target = fishlim_gui_prompt_target("Key Exchange", initial);
|
|
||||||
if (!target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
zoitechat_commandf(ph, "KEYX %s %s", target, mode);
|
|
||||||
g_free(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data) {
|
|
||||||
GtkTreeModel *model = gtk_tree_view_get_model(tree);
|
|
||||||
GtkTreeIter iter;
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
if (!gtk_tree_model_get_iter(model, &iter, path))
|
|
||||||
return;
|
|
||||||
|
|
||||||
gtk_tree_model_get(model, &iter, 0, &target, -1);
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(fishlim_target_entry), target);
|
|
||||||
g_free(target);
|
|
||||||
fishlim_gui_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fishlim_gui_destroy(GtkWidget *widget, gpointer data) {
|
|
||||||
fishlim_dialog = NULL;
|
|
||||||
fishlim_target_entry = NULL;
|
|
||||||
fishlim_key_entry = NULL;
|
|
||||||
fishlim_mode_combo = NULL;
|
|
||||||
fishlim_status_label = NULL;
|
|
||||||
fishlim_store = NULL;
|
|
||||||
fishlim_view = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_fishlim(char *word[], char *word_eol[], void *userdata) {
|
|
||||||
GtkWidget *content, *grid, *view, *scroll, *buttons, *button;
|
|
||||||
GtkCellRenderer *renderer;
|
|
||||||
const char *target;
|
|
||||||
|
|
||||||
target = *word_eol[2] ? word_eol[2] : zoitechat_get_info(ph, "channel");
|
|
||||||
|
|
||||||
if (fishlim_dialog) {
|
|
||||||
if (target)
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(fishlim_target_entry), target);
|
|
||||||
gtk_window_present(GTK_WINDOW(fishlim_dialog));
|
|
||||||
return ZOITECHAT_EAT_ZOITECHAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
fishlim_dialog = gtk_dialog_new_with_buttons("FiSHLiM Key Manager", NULL, GTK_DIALOG_DESTROY_WITH_PARENT, "_Close", GTK_RESPONSE_CLOSE, NULL);
|
|
||||||
gtk_window_set_default_size(GTK_WINDOW(fishlim_dialog), 520, 360);
|
|
||||||
g_signal_connect(fishlim_dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
|
|
||||||
g_signal_connect(fishlim_dialog, "destroy", G_CALLBACK(fishlim_gui_destroy), NULL);
|
|
||||||
|
|
||||||
content = gtk_dialog_get_content_area(GTK_DIALOG(fishlim_dialog));
|
|
||||||
grid = gtk_grid_new();
|
|
||||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 8);
|
|
||||||
gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
|
|
||||||
gtk_container_set_border_width(GTK_CONTAINER(grid), 12);
|
|
||||||
gtk_box_pack_start(GTK_BOX(content), grid, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
fishlim_target_entry = gtk_entry_new();
|
|
||||||
if (target)
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(fishlim_target_entry), target);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), gtk_label_new("Target nick or channel"), 0, 0, 1, 1);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), fishlim_target_entry, 1, 0, 2, 1);
|
|
||||||
|
|
||||||
fishlim_mode_combo = gtk_combo_box_text_new();
|
|
||||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fishlim_mode_combo), "ECB");
|
|
||||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fishlim_mode_combo), "CBC");
|
|
||||||
gtk_combo_box_set_active(GTK_COMBO_BOX(fishlim_mode_combo), 1);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), gtk_label_new("Mode"), 0, 1, 1, 1);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), fishlim_mode_combo, 1, 1, 2, 1);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), gtk_label_new("CBC may not work with older clients. Key exchange is private-message only."), 1, 2, 2, 1);
|
|
||||||
|
|
||||||
fishlim_key_entry = gtk_entry_new();
|
|
||||||
gtk_entry_set_visibility(GTK_ENTRY(fishlim_key_entry), FALSE);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), gtk_label_new("Key"), 0, 3, 1, 1);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), fishlim_key_entry, 1, 3, 2, 1);
|
|
||||||
|
|
||||||
buttons = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
|
|
||||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons), GTK_BUTTONBOX_END);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), buttons, 0, 4, 3, 1);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label("Set Key");
|
|
||||||
g_signal_connect(button, "clicked", G_CALLBACK(fishlim_gui_set), NULL);
|
|
||||||
gtk_container_add(GTK_CONTAINER(buttons), button);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label("Delete Key");
|
|
||||||
g_signal_connect(button, "clicked", G_CALLBACK(fishlim_gui_delete), NULL);
|
|
||||||
gtk_container_add(GTK_CONTAINER(buttons), button);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label("Private Message Key Exchange");
|
|
||||||
g_signal_connect(button, "clicked", G_CALLBACK(fishlim_gui_keyx), NULL);
|
|
||||||
gtk_container_add(GTK_CONTAINER(buttons), button);
|
|
||||||
|
|
||||||
fishlim_status_label = gtk_label_new(NULL);
|
|
||||||
gtk_label_set_xalign(GTK_LABEL(fishlim_status_label), 0.0);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), fishlim_status_label, 0, 5, 3, 1);
|
|
||||||
|
|
||||||
fishlim_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
|
||||||
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(fishlim_store));
|
|
||||||
fishlim_view = view;
|
|
||||||
renderer = gtk_cell_renderer_text_new();
|
|
||||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "Target", renderer, "text", 0, NULL);
|
|
||||||
renderer = gtk_cell_renderer_text_new();
|
|
||||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "Mode", renderer, "text", 1, NULL);
|
|
||||||
renderer = gtk_cell_renderer_text_new();
|
|
||||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "Status", renderer, "text", 2, NULL);
|
|
||||||
g_signal_connect(view, "row-activated", G_CALLBACK(fishlim_gui_row_activated), NULL);
|
|
||||||
|
|
||||||
scroll = gtk_scrolled_window_new(NULL, NULL);
|
|
||||||
gtk_widget_set_vexpand(scroll, TRUE);
|
|
||||||
gtk_container_add(GTK_CONTAINER(scroll), view);
|
|
||||||
gtk_grid_attach(GTK_GRID(grid), scroll, 0, 6, 3, 1);
|
|
||||||
|
|
||||||
g_signal_connect(fishlim_target_entry, "changed", G_CALLBACK(fishlim_gui_refresh_cb), NULL);
|
|
||||||
fishlim_gui_refresh();
|
|
||||||
|
|
||||||
gtk_widget_show_all(fishlim_dialog);
|
|
||||||
return ZOITECHAT_EAT_ZOITECHAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command handler for /setkey
|
* Command handler for /setkey
|
||||||
*/
|
*/
|
||||||
@@ -806,8 +490,6 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
|||||||
/* Set password */
|
/* Set password */
|
||||||
if (keystore_store_key(nick, key, mode)) {
|
if (keystore_store_key(nick, key, mode)) {
|
||||||
zoitechat_printf(ph, "Stored key for %s (%s)\n", nick, fish_modes[mode]);
|
zoitechat_printf(ph, "Stored key for %s (%s)\n", nick, fish_modes[mode]);
|
||||||
if (mode == FISH_CBC_MODE)
|
|
||||||
zoitechat_printf(ph, "Warning: CBC may not work with older clients.\n");
|
|
||||||
} else {
|
} else {
|
||||||
zoitechat_printf(ph, "\00305Failed to store key in addon_fishlim.conf\n");
|
zoitechat_printf(ph, "\00305Failed to store key in addon_fishlim.conf\n");
|
||||||
}
|
}
|
||||||
@@ -851,18 +533,8 @@ static int handle_keyx(char *word[], char *word_eol[], void *userdata) {
|
|||||||
const char *target = word[2];
|
const char *target = word[2];
|
||||||
zoitechat_context *query_ctx = NULL;
|
zoitechat_context *query_ctx = NULL;
|
||||||
char *pub_key, *priv_key;
|
char *pub_key, *priv_key;
|
||||||
enum fish_mode mode = FISH_CBC_MODE;
|
|
||||||
int ctx_type;
|
int ctx_type;
|
||||||
|
|
||||||
if (*word[3]) {
|
|
||||||
if (g_ascii_strcasecmp(word[3], "ECB") == 0)
|
|
||||||
mode = FISH_ECB_MODE;
|
|
||||||
else if (g_ascii_strcasecmp(word[3], "CBC") != 0) {
|
|
||||||
zoitechat_printf(ph, "%s", usage_keyx);
|
|
||||||
return ZOITECHAT_EAT_ALL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*target)
|
if (*target)
|
||||||
query_ctx = find_context_on_network(target);
|
query_ctx = find_context_on_network(target);
|
||||||
else {
|
else {
|
||||||
@@ -883,10 +555,8 @@ static int handle_keyx(char *word[], char *word_eol[], void *userdata) {
|
|||||||
if (dh1080_generate_key(&priv_key, &pub_key)) {
|
if (dh1080_generate_key(&priv_key, &pub_key)) {
|
||||||
g_hash_table_replace (pending_exchanges, g_ascii_strdown(target, -1), priv_key);
|
g_hash_table_replace (pending_exchanges, g_ascii_strdown(target, -1), priv_key);
|
||||||
|
|
||||||
zoitechat_commandf(ph, "quote NOTICE %s :DH1080_INIT %s%s", target, pub_key, (mode == FISH_CBC_MODE) ? " CBC" : "");
|
zoitechat_commandf(ph, "quote NOTICE %s :DH1080_INIT %s CBC", target, pub_key);
|
||||||
zoitechat_printf(ph, "Sent public key to %s (%s), waiting for reply...", target, fish_modes[mode]);
|
zoitechat_printf(ph, "Sent public key to %s (CBC), waiting for reply...", target);
|
||||||
if (mode == FISH_CBC_MODE)
|
|
||||||
zoitechat_printf(ph, "Warning: CBC may not work with older clients.");
|
|
||||||
|
|
||||||
g_free(pub_key);
|
g_free(pub_key);
|
||||||
} else {
|
} else {
|
||||||
@@ -1119,7 +789,6 @@ int zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
|
|||||||
*version = plugin_version;
|
*version = plugin_version;
|
||||||
|
|
||||||
/* Register commands */
|
/* Register commands */
|
||||||
zoitechat_hook_command(ph, "FISHLIM", ZOITECHAT_PRI_NORM, handle_fishlim, "Usage: FISHLIM, opens the FiSHLiM key manager", NULL);
|
|
||||||
zoitechat_hook_command(ph, "SETKEY", ZOITECHAT_PRI_NORM, handle_setkey, usage_setkey, NULL);
|
zoitechat_hook_command(ph, "SETKEY", ZOITECHAT_PRI_NORM, handle_setkey, usage_setkey, NULL);
|
||||||
zoitechat_hook_command(ph, "DELKEY", ZOITECHAT_PRI_NORM, handle_delkey, usage_delkey, NULL);
|
zoitechat_hook_command(ph, "DELKEY", ZOITECHAT_PRI_NORM, handle_delkey, usage_delkey, NULL);
|
||||||
zoitechat_hook_command(ph, "KEYX", ZOITECHAT_PRI_NORM, handle_keyx, usage_keyx, NULL);
|
zoitechat_hook_command(ph, "KEYX", ZOITECHAT_PRI_NORM, handle_keyx, usage_keyx, NULL);
|
||||||
@@ -1148,19 +817,12 @@ int zoitechat_plugin_init(zoitechat_plugin *plugin_handle,
|
|||||||
|
|
||||||
pending_exchanges = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
pending_exchanges = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
zoitechat_command(ph, "MENU ADD \"Window/FiSHLiM Key Manager\" \"FISHLIM\"");
|
|
||||||
zoitechat_command(ph, "MENU ADD \"$NICK/FiSHLiM Key Manager\" \"FISHLIM %s\"");
|
|
||||||
|
|
||||||
zoitechat_printf(ph, "%s plugin loaded\n", plugin_name);
|
zoitechat_printf(ph, "%s plugin loaded\n", plugin_name);
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zoitechat_plugin_deinit(void) {
|
int zoitechat_plugin_deinit(void) {
|
||||||
zoitechat_command(ph, "MENU DEL \"Window/FiSHLiM Key Manager\"");
|
|
||||||
zoitechat_command(ph, "MENU DEL \"$NICK/FiSHLiM Key Manager\"");
|
|
||||||
if (fishlim_dialog)
|
|
||||||
gtk_widget_destroy(fishlim_dialog);
|
|
||||||
g_clear_pointer(&pending_exchanges, g_hash_table_destroy);
|
g_clear_pointer(&pending_exchanges, g_hash_table_destroy);
|
||||||
dh1080_deinit();
|
dh1080_deinit();
|
||||||
fish_deinit();
|
fish_deinit();
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ cv_tabs_init (chanview *cv)
|
|||||||
GtkWidget *box;
|
GtkWidget *box;
|
||||||
GtkWidget *viewport;
|
GtkWidget *viewport;
|
||||||
GtkWidget *outer;
|
GtkWidget *outer;
|
||||||
|
GtkWidget *tree;
|
||||||
|
|
||||||
if (cv->vertical)
|
if (cv->vertical)
|
||||||
{
|
{
|
||||||
@@ -385,6 +386,11 @@ cv_tabs_init (chanview *cv)
|
|||||||
gtk_container_add (GTK_CONTAINER (viewport), box);
|
gtk_container_add (GTK_CONTAINER (viewport), box);
|
||||||
gtk_widget_show (box);
|
gtk_widget_show (box);
|
||||||
|
|
||||||
|
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (cv->store));
|
||||||
|
gtk_widget_set_name (tree, "zoitechat-tree");
|
||||||
|
gtk_widget_set_no_show_all (tree, TRUE);
|
||||||
|
gtk_box_pack_start (GTK_BOX (outer), tree, 0, 0, 0);
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (cv->box), outer);
|
gtk_container_add (GTK_CONTAINER (cv->box), outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user