0d537627fd3d1a71073ddf7b0bfb6cc9565c44dc
[claws.git] / src / plugins / managesieve / sieve_prefs.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2004-2015 the Claws Mail team
4  * Copyright (C) 2014-2015 Charles Lehner
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  * 
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #include "claws-features.h"
24 #endif
25
26 #include <gtk/gtk.h>
27 #include <glib.h>
28 #include <glib/gi18n.h>
29
30 #include "defs.h"
31 #include "gtk/gtkutils.h"
32 #include "gtk/combobox.h"
33 #include "alertpanel.h"
34 #include "passcrypt.h"
35 #include "utils.h"
36 #include "prefs.h"
37 #include "prefs_gtk.h"
38 #include "sieve_prefs.h"
39 #include "managesieve.h"
40
41 #define PREFS_BLOCK_NAME "ManageSieve"
42
43 SieveConfig sieve_config;
44
45 static PrefParam prefs[] = {
46         {"manager_win_width", "-1", &sieve_config.manager_win_width,
47                 P_INT, NULL, NULL, NULL},
48         {"manager_win_height", "-1", &sieve_config.manager_win_height,
49                 P_INT, NULL, NULL, NULL},
50         {0,0,0,0}
51 };
52
53 #define PACK_HBOX(hbox, vbox) \
54 { \
55         hbox = gtk_hbox_new (FALSE, 5); \
56         gtk_widget_show (hbox); \
57         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); \
58 }
59
60 #define RADIO_ADD(radio, group, hbox, vbox, label) \
61 { \
62         PACK_HBOX(hbox, vbox); \
63         gtk_container_set_border_width(GTK_CONTAINER (hbox), 0); \
64         radio = gtk_radio_button_new_with_label(group, label); \
65         group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); \
66         gtk_widget_show(radio); \
67         gtk_box_pack_start(GTK_BOX(hbox), radio, FALSE, FALSE, 0); \
68 }
69
70 struct SieveAccountPage
71 {
72         PrefsPage page;
73
74         GtkWidget *enable_checkbtn;
75         GtkWidget *serv_frame;
76         GtkWidget *auth_frame;
77         GtkWidget *host_checkbtn, *host_entry;
78         GtkWidget *port_checkbtn, *port_spinbtn;
79         GtkWidget *tls_radio_no, *tls_radio_maybe, *tls_radio_yes;
80         GtkWidget *auth_radio_noauth, *auth_radio_reuse, *auth_radio_custom;
81         GtkWidget *auth_custom_vbox, *auth_method_hbox;
82         GtkWidget *uid_entry;
83         GtkWidget *pass_entry;
84         GtkWidget *auth_menu;
85
86         PrefsAccount *account;
87 };
88
89 static struct SieveAccountPage account_page;
90
91 static void update_auth_sensitive(struct SieveAccountPage *page)
92 {
93         gboolean use_auth, custom;
94
95         custom = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->auth_radio_custom));
96         use_auth = custom || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->auth_radio_reuse));
97
98         gtk_widget_set_sensitive(GTK_WIDGET(page->auth_custom_vbox), custom);
99         gtk_widget_set_sensitive(GTK_WIDGET(page->auth_method_hbox), use_auth);
100 }
101
102 static void auth_toggled(GtkToggleButton *togglebutton,
103                 gpointer user_data)
104 {
105         struct SieveAccountPage *page = (struct SieveAccountPage *) user_data;
106         update_auth_sensitive(page);
107 }
108
109 static void sieve_prefs_account_create_widget_func(PrefsPage *_page,
110                                                  GtkWindow *window,
111                                                  gpointer data)
112 {
113         struct SieveAccountPage *page = (struct SieveAccountPage *) _page;
114         PrefsAccount *account = (PrefsAccount *) data;
115         SieveAccountConfig *config;
116
117         GtkWidget *page_vbox, *sieve_vbox;
118         GtkWidget *hbox;
119         GtkWidget *hbox_spc;
120
121         GtkWidget *enable_checkbtn;
122         GtkWidget *serv_vbox, *tls_frame;
123         GtkWidget *tls_vbox, *serv_frame;
124         GtkWidget *auth_vbox, *auth_frame;
125         GtkWidget *auth_custom_vbox, *auth_method_hbox;
126         GtkSizeGroup *size_group;
127         GtkWidget *host_checkbtn, *host_entry;
128         GtkWidget *port_checkbtn, *port_spinbtn;
129         GSList *tls_group = NULL;
130         GSList *auth_group = NULL;
131         GtkWidget *tls_radio_no, *tls_radio_maybe, *tls_radio_yes;
132         GtkWidget *auth_radio_noauth, *auth_radio_reuse, *auth_radio_custom;
133         GtkWidget *label;
134         GtkWidget *uid_entry;
135         GtkWidget *pass_entry;
136         GtkWidget *auth_menu;
137         GtkListStore *menu;
138         GtkTreeIter iter;
139
140         page_vbox = gtk_vbox_new (FALSE, VSPACING);
141         gtk_widget_show (page_vbox);
142         gtk_container_set_border_width (GTK_CONTAINER (page_vbox), VBOX_BORDER);
143
144         /* Enable/disable */
145         PACK_CHECK_BUTTON (page_vbox, enable_checkbtn,
146                            _("Enable Sieve"));
147
148         sieve_vbox = gtk_vbox_new (FALSE, VSPACING);
149         gtk_widget_show (sieve_vbox);
150         gtk_box_pack_start (GTK_BOX (page_vbox), sieve_vbox, FALSE, FALSE, 0);
151
152         /* Server info */
153         serv_vbox = gtkut_get_options_frame(sieve_vbox, &serv_frame, _("Server information"));
154         gtk_widget_show (serv_vbox);
155         gtk_box_pack_start (GTK_BOX (page_vbox), serv_vbox, FALSE, FALSE, 0);
156
157         SET_TOGGLE_SENSITIVITY (enable_checkbtn, sieve_vbox);
158         size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
159
160         /* Server name */
161         PACK_HBOX (hbox, serv_vbox);
162         PACK_CHECK_BUTTON (hbox, host_checkbtn, _("Server name"));
163         gtk_size_group_add_widget(size_group, host_checkbtn);
164
165         host_entry = gtk_entry_new();
166         gtk_entry_set_max_length(GTK_ENTRY(host_entry), 255);
167         gtk_widget_show (host_entry);
168         gtk_box_pack_start (GTK_BOX (hbox), host_entry, TRUE, TRUE, 0);
169         SET_TOGGLE_SENSITIVITY (host_checkbtn, host_entry);
170         CLAWS_SET_TIP(hbox,
171                 _("Connect to this host instead of the host used for receiving mail"));
172
173         /* Port */
174         PACK_HBOX (hbox, serv_vbox);
175         PACK_CHECK_BUTTON (hbox, port_checkbtn, _("Server port"));
176         port_spinbtn = gtk_spin_button_new_with_range(1, 65535, 1);
177         gtk_widget_show (port_spinbtn);
178         gtk_box_pack_start (GTK_BOX (hbox), port_spinbtn, FALSE, FALSE, 0);
179         SET_TOGGLE_SENSITIVITY (port_checkbtn, port_spinbtn);
180         gtk_size_group_add_widget(size_group, port_checkbtn);
181         CLAWS_SET_TIP(hbox,
182                 _("Connect to this port instead of the default"));
183
184         /* Encryption */
185
186         tls_vbox = gtkut_get_options_frame(sieve_vbox, &tls_frame, _("Encryption"));
187         gtk_widget_show (tls_vbox);
188         gtk_box_pack_start (GTK_BOX (page_vbox), tls_vbox, FALSE, FALSE, 0);
189
190         RADIO_ADD(tls_radio_no, tls_group, hbox, tls_vbox,
191                         _("No TLS"));
192         RADIO_ADD(tls_radio_maybe, tls_group, hbox, tls_vbox,
193                         _("Use TLS when available"));
194         RADIO_ADD(tls_radio_yes, tls_group, hbox, tls_vbox,
195                         _("Require TLS"));
196
197         /* Authentication */
198
199         auth_vbox = gtkut_get_options_frame(sieve_vbox, &auth_frame,
200                         _("Authentication"));
201
202         RADIO_ADD(auth_radio_noauth, auth_group, hbox, auth_vbox,
203                 _("No authentication"));
204         RADIO_ADD(auth_radio_reuse, auth_group, hbox, auth_vbox,
205                 _("Use same authentication as for receiving mail"));
206         RADIO_ADD(auth_radio_custom, auth_group, hbox, auth_vbox,
207                 _("Specify authentication"));
208
209         g_signal_connect(G_OBJECT(auth_radio_custom), "toggled",
210                         G_CALLBACK(auth_toggled), page);
211         g_signal_connect(G_OBJECT(auth_radio_reuse), "toggled",
212                         G_CALLBACK(auth_toggled), page);
213
214         /* Custom Auth Settings */
215
216         hbox = gtk_hbox_new (FALSE, 0);
217         gtk_widget_show (hbox);
218         gtk_box_pack_start (GTK_BOX (auth_vbox), hbox, FALSE, FALSE, 0);
219
220         hbox_spc = gtk_hbox_new (FALSE, 0);
221         gtk_widget_show (hbox_spc);
222         gtk_box_pack_start (GTK_BOX (hbox), hbox_spc, FALSE, FALSE, 0);
223         gtk_widget_set_size_request (hbox_spc, 12, -1);
224
225         auth_custom_vbox = gtk_vbox_new (FALSE, VSPACING/2);
226         gtk_widget_show (auth_custom_vbox);
227         gtk_container_set_border_width (GTK_CONTAINER (auth_custom_vbox), 0);
228         gtk_box_pack_start (GTK_BOX (hbox), auth_custom_vbox, TRUE, TRUE, 0);
229
230         /* User ID + Password */
231
232         hbox = gtk_hbox_new (FALSE, 8);
233         gtk_widget_show (hbox);
234         gtk_box_pack_start (GTK_BOX (auth_custom_vbox), hbox, FALSE, FALSE, 0);
235
236         /* User ID*/
237         label = gtk_label_new (_("User ID"));
238         gtk_widget_show (label);
239         gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
240
241         uid_entry = gtk_entry_new ();
242         gtk_widget_show (uid_entry);
243         gtk_widget_set_size_request (uid_entry, DEFAULT_ENTRY_WIDTH, -1);
244         gtk_box_pack_start (GTK_BOX (hbox), uid_entry, TRUE, TRUE, 0);
245
246         /* Password */
247         label = gtk_label_new (_("Password"));
248         gtk_widget_show (label);
249         gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
250
251         pass_entry = gtk_entry_new ();
252         gtk_widget_show (pass_entry);
253         gtk_widget_set_size_request (pass_entry, DEFAULT_ENTRY_WIDTH, -1);
254         gtk_entry_set_visibility (GTK_ENTRY (pass_entry), FALSE);
255         gtk_box_pack_start (GTK_BOX (hbox), pass_entry, TRUE, TRUE, 0);
256
257         /* Authentication method */
258
259         auth_method_hbox = gtk_hbox_new (FALSE, 8);
260         gtk_widget_show (auth_method_hbox);
261         gtk_box_pack_start (GTK_BOX (auth_vbox), auth_method_hbox, FALSE, FALSE, 0);
262
263         label = gtk_label_new (_("Authentication method"));
264         gtk_widget_show (label);
265         gtk_box_pack_start (GTK_BOX (auth_method_hbox), label, FALSE, FALSE, 0);
266
267         auth_menu = gtkut_sc_combobox_create(NULL, FALSE);
268         menu = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(auth_menu)));
269         gtk_widget_show (auth_menu);
270         gtk_box_pack_start (GTK_BOX (auth_method_hbox), auth_menu, FALSE, FALSE, 0);
271
272         COMBOBOX_ADD (menu, _("Automatic"), SIEVEAUTH_AUTO);
273         COMBOBOX_ADD (menu, NULL, 0);
274         COMBOBOX_ADD (menu, "PLAIN", SIEVEAUTH_PLAIN);
275         COMBOBOX_ADD (menu, "LOGIN", SIEVEAUTH_LOGIN);
276         COMBOBOX_ADD (menu, "CRAM-MD5", SIEVEAUTH_CRAM_MD5);
277
278         /* Populate config */
279
280         config = sieve_prefs_account_get_config(account);
281
282         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_checkbtn), config->enable);
283         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(host_checkbtn), config->use_host);
284         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(port_checkbtn), config->use_port);
285         gtk_spin_button_set_value(GTK_SPIN_BUTTON(port_spinbtn), (float) config->port);
286
287         if (config->host != NULL)
288                 gtk_entry_set_text(GTK_ENTRY(host_entry), config->host);
289         if (config->userid != NULL)
290                 gtk_entry_set_text(GTK_ENTRY(uid_entry), config->userid);
291         if (config->passwd != NULL)
292                 gtk_entry_set_text(GTK_ENTRY(pass_entry), config->passwd);
293
294         combobox_select_by_data(GTK_COMBO_BOX(auth_menu), config->auth_type);
295
296         /* Add items to page struct */
297         page->account = account;
298         page->enable_checkbtn = enable_checkbtn;
299         page->serv_frame = serv_frame;
300         page->auth_frame = auth_frame;
301         page->auth_custom_vbox = auth_custom_vbox;
302         page->auth_method_hbox = auth_method_hbox;
303         page->host_checkbtn = host_checkbtn;
304         page->host_entry = host_entry;
305         page->port_checkbtn = port_checkbtn;
306         page->port_spinbtn = port_spinbtn;
307         page->auth_radio_noauth = auth_radio_noauth;
308         page->auth_radio_reuse = auth_radio_reuse;
309         page->auth_radio_custom = auth_radio_custom;
310         page->tls_radio_no = tls_radio_no;
311         page->tls_radio_maybe = tls_radio_maybe;
312         page->tls_radio_yes = tls_radio_yes;
313         page->uid_entry = uid_entry;
314         page->pass_entry = pass_entry;
315         page->auth_menu = auth_menu;
316         page->page.widget = page_vbox;
317
318         /* Update things */
319
320         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
321                                 config->tls_type == SIEVE_TLS_NO ? tls_radio_no :
322                                 config->tls_type == SIEVE_TLS_MAYBE ? tls_radio_maybe :
323                                 tls_radio_yes), TRUE);
324
325         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
326                                 config->auth == SIEVEAUTH_REUSE ? auth_radio_reuse :
327                                 config->auth == SIEVEAUTH_CUSTOM ? auth_radio_custom :
328                                 auth_radio_noauth), TRUE);
329
330         update_auth_sensitive(page);
331
332         /* Free things */
333         g_object_unref(G_OBJECT(size_group));
334 }
335
336 static void sieve_prefs_account_destroy_widget_func(PrefsPage *_page)
337 {
338 }
339
340 static gint sieve_prefs_account_apply(struct SieveAccountPage *page)
341 {
342         SieveAccountConfig *config;
343
344         config = sieve_prefs_account_get_config(page->account);
345
346         config->enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->enable_checkbtn));
347         config->use_port = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->port_checkbtn));
348         config->use_host = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->host_checkbtn));
349         config->port = (gushort)gtk_spin_button_get_value_as_int
350                         (GTK_SPIN_BUTTON(page->port_spinbtn));
351
352         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->auth_radio_noauth)))
353                 config->auth = SIEVEAUTH_NONE;
354         else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->auth_radio_reuse)))
355                 config->auth = SIEVEAUTH_REUSE;
356         else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->auth_radio_custom)))
357                 config->auth = SIEVEAUTH_CUSTOM;
358
359         config->tls_type =
360                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->tls_radio_no)) ?
361                         SIEVE_TLS_NO :
362                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->tls_radio_maybe)) ?
363                         SIEVE_TLS_MAYBE :
364                         SIEVE_TLS_YES;
365
366         config->host = gtk_editable_get_chars(GTK_EDITABLE(page->host_entry), 0, -1);
367         config->userid = gtk_editable_get_chars(GTK_EDITABLE(page->uid_entry), 0, -1);
368         config->passwd = gtk_editable_get_chars(GTK_EDITABLE(page->pass_entry), 0, -1);
369         config->auth_type = combobox_get_active_data(GTK_COMBO_BOX(page->auth_menu));
370
371         sieve_prefs_account_set_config(page->account, config);
372         sieve_prefs_account_free_config(config);
373         return TRUE;
374 }
375
376 static gboolean sieve_prefs_account_check(struct SieveAccountPage *page)
377 {
378         if (strchr(gtk_entry_get_text(GTK_ENTRY(page->host_entry)), ' ')) {
379                 alertpanel_error(_("Sieve server must not contain a space."));
380                 return FALSE;
381         }
382
383         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->host_checkbtn)) &&
384                         *gtk_entry_get_text(GTK_ENTRY(page->host_entry)) == '\0') {
385                 alertpanel_error(_("Sieve server is not entered."));
386                 return FALSE;
387         }
388
389         return TRUE;
390 }
391
392 static void sieve_prefs_account_save_func(PrefsPage *_page)
393 {
394         struct SieveAccountPage *page = (struct SieveAccountPage *) _page;
395         if (sieve_prefs_account_check(page)) {
396                 sieve_prefs_account_apply(page);
397         }
398 }
399
400 static gboolean sieve_prefs_account_can_close(PrefsPage *_page)
401 {
402         struct SieveAccountPage *page = (struct SieveAccountPage *) _page;
403         return sieve_prefs_account_check(page);
404 }
405
406 void sieve_prefs_init()
407 {
408         gchar *rcpath;
409
410         /* Account prefs */
411         static gchar *path[3];
412         path[0] = _("Plugins");
413         path[1] = _("Sieve");
414         path[2] = NULL;
415
416         account_page.page.path = path;
417         account_page.page.create_widget = sieve_prefs_account_create_widget_func;
418         account_page.page.destroy_widget = sieve_prefs_account_destroy_widget_func;
419         account_page.page.save_page = sieve_prefs_account_save_func;
420         account_page.page.can_close = sieve_prefs_account_can_close;
421         account_page.page.weight = 30.0;
422         prefs_account_register_page((PrefsPage *) &account_page);
423
424         /* Common prefs */
425         prefs_set_default(prefs);
426         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
427         prefs_read_config(prefs, PREFS_BLOCK_NAME, rcpath, NULL);
428         g_free(rcpath);
429 }
430
431 void sieve_prefs_done(void)
432 {
433         PrefFile *pref_file;
434         gchar *rc_file_path;
435
436         prefs_account_unregister_page((PrefsPage *) &account_page);
437
438         rc_file_path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
439                                    COMMON_RC, NULL);
440         pref_file = prefs_write_open(rc_file_path);
441         g_free(rc_file_path);
442
443         if (!pref_file || prefs_set_block_label(pref_file, PREFS_BLOCK_NAME) < 0)
444                 return;
445
446         if (prefs_write_param(prefs, pref_file->fp) < 0) {
447                 g_warning("failed to write ManageSieve Plugin configuration");
448                 prefs_file_close_revert(pref_file);
449                 return;
450         }
451
452         if (fprintf(pref_file->fp, "\n") < 0) {
453                 FILE_OP_ERROR(rc_file_path, "fprintf");
454                 prefs_file_close_revert(pref_file);
455         } else
456                 prefs_file_close(pref_file);
457 }
458
459 struct SieveAccountConfig *sieve_prefs_account_get_config(
460                 PrefsAccount *account)
461 {
462         SieveAccountConfig *config;
463         const gchar *confstr;
464         gchar enc_userid[256], enc_passwd[256];
465         gchar enable, use_host, use_port;
466         guchar tls_type, auth, auth_type;
467         gsize len;
468 #if defined(G_OS_WIN32) || defined(__OpenBSD__)
469         /* Windows sscanf() does not understand the %ms format yet, so we
470          * have to do the allocation of target buffer ourselves before
471          * calling sscanf(), and copy the host string to config->host.
472          */
473         gchar tmphost[256];
474 #endif
475
476         config = g_new0(SieveAccountConfig, 1);
477
478         config->enable = FALSE;
479         config->use_host = FALSE;
480         config->host = NULL;
481         config->use_port = FALSE;
482         config->port = 4190;
483         config->tls_type = SIEVE_TLS_YES;
484         config->auth = SIEVEAUTH_REUSE;
485         config->auth_type = SIEVEAUTH_AUTO;
486         config->userid = NULL;
487         config->passwd = NULL;
488
489         confstr = prefs_account_get_privacy_prefs(account, "sieve");
490         if (confstr == NULL)
491                 return config;
492
493 #if defined(G_OS_WIN32) || defined(__OpenBSD__)
494         sscanf(confstr, "%c%c %255s %c%hu %hhu %hhu %hhu %255s %255s",
495 #else
496         sscanf(confstr, "%c%c %ms %c%hu %hhu %hhu %hhu %255s %255s",
497 #endif
498                         &enable, &use_host,
499 #if defined(G_OS_WIN32) || defined(__OpenBSD__)
500                         tmphost,
501 #else
502                         &config->host,
503 #endif
504                         &use_port, &config->port,
505                         &tls_type,
506                         &auth,
507                         &auth_type,
508                         enc_userid,
509                         enc_passwd);
510
511         /* Scan enums separately, for endian purposes */
512         config->tls_type = tls_type;
513         config->auth = auth;
514         config->auth_type = auth_type;
515
516 #if defined(G_OS_WIN32) || defined(__OpenBSD__)
517         config->host = g_strndup(tmphost, 255);
518 #endif
519
520         config->enable = enable == 'y';
521         config->use_host = use_host == 'y';
522         config->use_port = use_port == 'y';
523
524         if (config->host[0] == '!' && !config->host[1]) {
525                 g_free(config->host);
526                 config->host = NULL;
527         }
528
529         config->userid = g_base64_decode(enc_userid, &len);
530         config->passwd = g_base64_decode(enc_passwd, &len);
531         passcrypt_decrypt(config->passwd, len);
532
533         return config;
534 }
535
536 void sieve_prefs_account_set_config(
537                 PrefsAccount *account, SieveAccountConfig *config)
538 {
539         gchar *confstr = NULL;
540         gchar *enc_userid = NULL;
541         gchar *enc_passwd = NULL;
542         gchar *tmp;
543         gsize len;
544
545         if (config->userid) {
546                 len = strlen(config->userid);
547                 enc_userid = g_base64_encode(config->userid, len);
548         }
549
550         if (config->passwd) {
551                 tmp = g_strdup(config->passwd);
552                 len = strlen(tmp);
553                 passcrypt_encrypt(tmp, len);
554                 enc_passwd = g_base64_encode(tmp, len);
555                 g_free(tmp);
556         }
557
558         confstr = g_strdup_printf("%c%c %s %c%hu %hhu %hhu %hhu %s %s",
559                         config->enable ? 'y' : 'n',
560                         config->use_host ? 'y' : 'n',
561                         config->host && config->host[0] ? config->host : "!",
562                         config->use_port ? 'y' : 'n',
563                         config->port,
564                         config->tls_type,
565                         config->auth,
566                         config->auth_type,
567                         enc_userid ? enc_userid : "",
568                         enc_passwd ? enc_passwd : "");
569
570         if (enc_userid)
571                 g_free(enc_userid);
572         if (enc_passwd)
573                 g_free(enc_passwd);
574
575         prefs_account_set_privacy_prefs(account, "sieve", confstr);
576
577         g_free(confstr);
578
579         sieve_account_prefs_updated(account);
580 }
581
582 void sieve_prefs_account_free_config(SieveAccountConfig *config)
583 {
584         g_free(config->host);
585         g_free(config->userid);
586         g_free(config->passwd);
587         g_free(config);
588 }
589