mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-17 20:19:24 +00:00
Compare commits
3 Commits
master
...
fishlim-ma
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ded7ef830 | |||
| adb18b7ce3 | |||
| b09af655e7 |
@@ -1,102 +0,0 @@
|
|||||||
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);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
|
||||||
|
|||||||
@@ -194,6 +194,18 @@ 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.
|
||||||
*/
|
*/
|
||||||
@@ -217,6 +229,7 @@ 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,6 +33,7 @@
|
|||||||
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, zoitechat_plugin_dep, libssl_dep],
|
dependencies: [libgio_dep, gtk_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,6 +27,7 @@
|
|||||||
#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"
|
||||||
@@ -44,7 +45,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>], performs DH1080 key-exchange with <nick>";
|
static const char usage_keyx[] = "Usage: KEYX [<nick>] [ECB|CBC], 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>";
|
||||||
@@ -52,6 +53,13 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -455,6 +463,314 @@ 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
|
||||||
*/
|
*/
|
||||||
@@ -490,6 +806,8 @@ 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");
|
||||||
}
|
}
|
||||||
@@ -533,8 +851,18 @@ 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 {
|
||||||
@@ -555,8 +883,10 @@ 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 CBC", target, pub_key);
|
zoitechat_commandf(ph, "quote NOTICE %s :DH1080_INIT %s%s", target, pub_key, (mode == FISH_CBC_MODE) ? " CBC" : "");
|
||||||
zoitechat_printf(ph, "Sent public key to %s (CBC), waiting for reply...", target);
|
zoitechat_printf(ph, "Sent public key to %s (%s), waiting for reply...", target, fish_modes[mode]);
|
||||||
|
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 {
|
||||||
@@ -789,6 +1119,7 @@ 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);
|
||||||
@@ -817,12 +1148,19 @@ 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,7 +341,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -386,11 +385,6 @@ 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