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