#include "gtk/combobox.h"
#include "alertpanel.h"
#include "passcrypt.h"
+#include "password.h"
+#include "passwordstore.h"
#include "utils.h"
#include "prefs.h"
#include "prefs_gtk.h"
#include "sieve_prefs.h"
#include "managesieve.h"
+#define PREFS_BLOCK_NAME "ManageSieve"
+
+SieveConfig sieve_config;
+
+static PrefParam prefs[] = {
+ {"manager_win_width", "-1", &sieve_config.manager_win_width,
+ P_INT, NULL, NULL, NULL},
+ {"manager_win_height", "-1", &sieve_config.manager_win_height,
+ P_INT, NULL, NULL, NULL},
+ {0,0,0,0,0,0,0}
+};
+
#define PACK_HBOX(hbox, vbox) \
{ \
hbox = gtk_hbox_new (FALSE, 5); \
struct SieveAccountPage *page = (struct SieveAccountPage *) _page;
PrefsAccount *account = (PrefsAccount *) data;
SieveAccountConfig *config;
+ gchar *pass;
GtkWidget *page_vbox, *sieve_vbox;
GtkWidget *hbox;
/* Server info */
serv_vbox = gtkut_get_options_frame(sieve_vbox, &serv_frame, _("Server information"));
- gtk_widget_show (serv_vbox);
- gtk_box_pack_start (GTK_BOX (page_vbox), serv_vbox, FALSE, FALSE, 0);
SET_TOGGLE_SENSITIVITY (enable_checkbtn, sieve_vbox);
size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
/* Encryption */
tls_vbox = gtkut_get_options_frame(sieve_vbox, &tls_frame, _("Encryption"));
- gtk_widget_show (tls_vbox);
- gtk_box_pack_start (GTK_BOX (page_vbox), tls_vbox, FALSE, FALSE, 0);
RADIO_ADD(tls_radio_no, tls_group, hbox, tls_vbox,
- _("No TLS"));
+ _("No encryption"));
RADIO_ADD(tls_radio_maybe, tls_group, hbox, tls_vbox,
- _("Use TLS when available"));
+ _("Use STARTTLS when available"));
RADIO_ADD(tls_radio_yes, tls_group, hbox, tls_vbox,
- _("Require TLS"));
+ _("Require STARTTLS"));
/* Authentication */
gtk_entry_set_text(GTK_ENTRY(host_entry), config->host);
if (config->userid != NULL)
gtk_entry_set_text(GTK_ENTRY(uid_entry), config->userid);
- if (config->passwd != NULL)
- gtk_entry_set_text(GTK_ENTRY(pass_entry), config->passwd);
+ if ((pass = passwd_store_get_account(account->account_id,
+ "sieve")) != NULL) {
+ gtk_entry_set_text(GTK_ENTRY(pass_entry), pass);
+ memset(pass, 0, strlen(pass));
+ g_free(pass);
+ }
combobox_select_by_data(GTK_COMBO_BOX(auth_menu), config->auth_type);
/* Free things */
g_object_unref(G_OBJECT(size_group));
+
+ sieve_prefs_account_free_config(config);
}
static void sieve_prefs_account_destroy_widget_func(PrefsPage *_page)
SIEVE_TLS_MAYBE :
SIEVE_TLS_YES;
+ g_free(config->host);
+ g_free(config->userid);
+
config->host = gtk_editable_get_chars(GTK_EDITABLE(page->host_entry), 0, -1);
config->userid = gtk_editable_get_chars(GTK_EDITABLE(page->uid_entry), 0, -1);
- config->passwd = gtk_editable_get_chars(GTK_EDITABLE(page->pass_entry), 0, -1);
+ gchar *pwd = gtk_editable_get_chars(GTK_EDITABLE(page->pass_entry), 0, -1);
+ passwd_store_set_account(page->account->account_id, "sieve", pwd, FALSE);
+ memset(pwd, 0, strlen(pwd));
+ g_free(pwd);
config->auth_type = combobox_get_active_data(GTK_COMBO_BOX(page->auth_menu));
sieve_prefs_account_set_config(page->account, config);
void sieve_prefs_init()
{
+ gchar *rcpath;
+
+ /* Account prefs */
static gchar *path[3];
path[0] = _("Plugins");
path[1] = _("Sieve");
account_page.page.can_close = sieve_prefs_account_can_close;
account_page.page.weight = 30.0;
prefs_account_register_page((PrefsPage *) &account_page);
+
+ /* Common prefs */
+ prefs_set_default(prefs);
+ rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
+ prefs_read_config(prefs, PREFS_BLOCK_NAME, rcpath, NULL);
+ g_free(rcpath);
}
void sieve_prefs_done(void)
{
+ PrefFile *pref_file;
+ gchar *rc_file_path;
+
prefs_account_unregister_page((PrefsPage *) &account_page);
+
+ rc_file_path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ COMMON_RC, NULL);
+ pref_file = prefs_write_open(rc_file_path);
+ g_free(rc_file_path);
+
+ if (!pref_file || prefs_set_block_label(pref_file, PREFS_BLOCK_NAME) < 0)
+ return;
+
+ if (prefs_write_param(prefs, pref_file->fp) < 0) {
+ g_warning("failed to write ManageSieve Plugin configuration");
+ prefs_file_close_revert(pref_file);
+ return;
+ }
+
+ if (fprintf(pref_file->fp, "\n") < 0) {
+ FILE_OP_ERROR(rc_file_path, "fprintf");
+ prefs_file_close_revert(pref_file);
+ } else
+ prefs_file_close(pref_file);
}
struct SieveAccountConfig *sieve_prefs_account_get_config(
const gchar *confstr;
gchar enc_userid[256], enc_passwd[256];
gchar enable, use_host, use_port;
+ guchar tls_type, auth, auth_type;
gsize len;
-#ifdef G_OS_WIN32
- /* Windows sscanf() does not understand the %ms format yet, so we
+ gint num;
+#if defined(G_OS_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ /* Non-GNU sscanf() does not understand the %ms format, so we
* have to do the allocation of target buffer ourselves before
* calling sscanf(), and copy the host string to config->host.
*/
config->auth = SIEVEAUTH_REUSE;
config->auth_type = SIEVEAUTH_AUTO;
config->userid = NULL;
- config->passwd = NULL;
confstr = prefs_account_get_privacy_prefs(account, "sieve");
if (confstr == NULL)
return config;
-#ifdef G_OS_WIN32
- sscanf(confstr, "%c%c %255s %c%hu %hhu %hhu %hhu %255s %255s",
+ enc_userid[0] = '\0';
+ enc_passwd[0] = '\0';
+#if defined(G_OS_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ if ((num = sscanf(confstr, "%c%c %255s %c%hu %hhu %hhu %hhu %255s %255s",
#else
- sscanf(confstr, "%c%c %ms %c%hu %hhu %hhu %hhu %255s %255s",
+ if ((num = sscanf(confstr, "%c%c %ms %c%hu %hhu %hhu %hhu %255s %255s",
#endif
&enable, &use_host,
-#ifdef G_OS_WIN32
+#if defined(G_OS_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
tmphost,
#else
&config->host,
#endif
&use_port, &config->port,
- (char *)&config->tls_type,
- (char *)&config->auth,
- (char *)&config->auth_type,
+ &tls_type,
+ &auth,
+ &auth_type,
enc_userid,
- enc_passwd);
+ enc_passwd)) != 10) {
+ /* This (10th element missing) will happen on any recent
+ * configuration, where the password is already in
+ * passwordstore, and not in this config string. We have
+ * to read the 10th element in order not to break older
+ * configurations, and to move the password to password
+ * store.
+ * The userid may be missing if it is unset.
+ * If there are not 10, 9 or 8 elements, something is wrong. */
+ if (num != 9 && num != 8) {
+ g_warning("failed reading Sieve config elements");
+ }
+ }
+ debug_print("Read %d Sieve config elements\n", num);
+
+ /* Scan enums separately, for endian purposes */
+ config->tls_type = tls_type;
+ config->auth = auth;
+ config->auth_type = auth_type;
-#ifdef G_OS_WIN32
+#if defined(G_OS_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
config->host = g_strndup(tmphost, 255);
#endif
config->use_host = use_host == 'y';
config->use_port = use_port == 'y';
- if (config->host[0] == '!' && !config->host[1]) {
+ if (config->host != NULL && config->host[0] == '!' && !config->host[1]) {
g_free(config->host);
config->host = NULL;
}
config->userid = g_base64_decode(enc_userid, &len);
- config->passwd = g_base64_decode(enc_passwd, &len);
- passcrypt_decrypt(config->passwd, len);
+
+ /* migrate password from passcrypt to passwordstore, if
+ * it's not there yet */
+ if (enc_passwd[0] != '\0' &&
+ !passwd_store_has_password_account(account->account_id, "sieve")) {
+ gchar *pass = g_base64_decode(enc_passwd, &len);
+ passcrypt_decrypt(pass, len);
+ passwd_store_set_account(account->account_id, "sieve",
+ pass, FALSE);
+ g_free(pass);
+ }
return config;
}
{
gchar *confstr = NULL;
gchar *enc_userid = NULL;
- gchar *enc_passwd = NULL;
- gchar *tmp;
gsize len;
if (config->userid) {
enc_userid = g_base64_encode(config->userid, len);
}
- if (config->passwd) {
- tmp = g_strdup(config->passwd);
- len = strlen(tmp);
- passcrypt_encrypt(tmp, len);
- enc_passwd = g_base64_encode(tmp, len);
- g_free(tmp);
- }
-
- confstr = g_strdup_printf("%c%c %s %c%hu %hhu %hhu %hhu %s %s",
+ confstr = g_strdup_printf("%c%c %s %c%hu %hu %hu %hu %s",
config->enable ? 'y' : 'n',
config->use_host ? 'y' : 'n',
config->host && config->host[0] ? config->host : "!",
config->tls_type,
config->auth,
config->auth_type,
- enc_userid ? enc_userid : "",
- enc_passwd ? enc_passwd : "");
+ enc_userid ? enc_userid : "");
if (enc_userid)
g_free(enc_userid);
- if (enc_passwd)
- g_free(enc_passwd);
prefs_account_set_privacy_prefs(account, "sieve", confstr);
{
g_free(config->host);
g_free(config->userid);
- g_free(config->passwd);
g_free(config);
}