static void default_mode_radio_button_cb(GtkToggleButton *button, gpointer data) { guint mode; gboolean is_url; if (gtk_toggle_button_get_active(button) != TRUE) return; mode = *((guint *)data); is_url = (mode == DEF_MODE_URL)? TRUE: FALSE; gtk_widget_set_sensitive(libravatarprefs_page.defm_url_text, is_url); if (is_url) /* custom URL requires following redirects */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(libravatarprefs_page.allow_redirects_check), TRUE); if (mode == DEF_MODE_NONE) { prefs_common_get_prefs()->enable_avatars = AVATARS_ENABLE_BOTH; } else { /* don't waste time with headers that won't be displayed */ prefs_common_get_prefs()->enable_avatars = AVATARS_DISABLE; /* empty missing cache when switching to generated */ g_hash_table_remove_all(libravatarmisses); } }
static guchar *_make_key_deriv(const gchar *passphrase, guint rounds, guint length) { guchar *kd, *salt; gchar *saltpref = prefs_common_get_prefs()->master_passphrase_salt; gsize saltlen; gint ret; /* Grab our salt, generating and saving a new random one if needed. */ if (saltpref == NULL || strlen(saltpref) == 0) { _generate_salt(); saltpref = prefs_common_get_prefs()->master_passphrase_salt; } salt = g_base64_decode(saltpref, &saltlen); kd = g_malloc0(length); START_TIMING("PBKDF2"); ret = pkcs5_pbkdf2(passphrase, strlen(passphrase), salt, saltlen, kd, length, rounds); END_TIMING(); g_free(salt); if (ret == 0) { return kd; } g_free(kd); return NULL; }
const gboolean master_passphrase_is_set() { if (prefs_common_get_prefs()->master_passphrase == NULL || strlen(prefs_common_get_prefs()->master_passphrase) == 0) return FALSE; return TRUE; }
static AttachWarnerMention *aw_matcherlist_string_match(MatcherList *matchers, gchar *str, gchar *sig_separator) { MsgInfo info; int i = 0; gboolean ret = FALSE; gchar **lines = NULL; AttachWarnerMention *awm = NULL; if (str == NULL || *str == '\0') { return awm; } lines = g_strsplit(str, "\n", -1); if (attwarnerprefs.skip_quotes && *prefs_common_get_prefs()->quote_chars != '\0') { debug_print("checking without quotes\n"); for (i = 0; lines[i] != NULL && ret == FALSE; i++) { if(attwarnerprefs.skip_signature && sig_separator != NULL && *sig_separator != '\0' && strcmp(lines[i], sig_separator) == 0) { debug_print("reached signature delimiter at line %d\n", i); break; } if (line_has_quote_char(lines[i], prefs_common_get_prefs()->quote_chars) == NULL) { debug_print("testing line %d\n", i); info.subject = lines[i]; ret = matcherlist_match(matchers, &info); debug_print("line %d: %d\n", i, ret); } } } else { debug_print("checking with quotes\n"); for (i = 0; lines[i] != NULL && ret == FALSE; i++) { if(attwarnerprefs.skip_signature && sig_separator != NULL && *sig_separator != '\0' && strcmp(lines[i], sig_separator) == 0) { debug_print("reached signature delimiter at line %d\n", i); break; } debug_print("testing line %d\n", i); info.subject = lines[i]; ret = matcherlist_match(matchers, &info); debug_print("line %d: %d\n", i, ret); } } if (ret != FALSE) { awm = g_new0(AttachWarnerMention, 1); awm->line = i; /* usual humans count lines from 1 */ awm->context = g_strdup(lines[i - 1]); debug_print("found at line %d, context \"%s\"\n", awm->line, awm->context); } g_strfreev(lines); return awm; }
void master_passphrase_change(const gchar *oldp, const gchar *newp) { guchar *kd; gchar *base64_kd; guint rounds = prefs_common_get_prefs()->master_passphrase_pbkdf2_rounds; g_return_if_fail(rounds > 0); if (oldp == NULL) { /* If oldp is NULL, make sure the user has to enter the * current master passphrase before being able to change it. */ master_passphrase_forget(); oldp = master_passphrase(); } g_return_if_fail(oldp != NULL); /* Update master passphrase hash in prefs */ if (prefs_common_get_prefs()->master_passphrase != NULL) g_free(prefs_common_get_prefs()->master_passphrase); if (newp != NULL) { debug_print("Storing key derivation of new master passphrase\n"); kd = _make_key_deriv(newp, rounds, KD_LENGTH); base64_kd = g_base64_encode(kd, 64); prefs_common_get_prefs()->master_passphrase = g_strdup_printf("{PBKDF2-HMAC-SHA1,%d}%s", rounds, base64_kd); g_free(kd); g_free(base64_kd); } else { debug_print("Setting master_passphrase to NULL\n"); prefs_common_get_prefs()->master_passphrase = NULL; } /* Now go over all accounts, reencrypting their passwords using * the new master passphrase. */ if (oldp == NULL) oldp = PASSCRYPT_KEY; if (newp == NULL) newp = PASSCRYPT_KEY; debug_print("Reencrypting all account passwords...\n"); passwd_store_reencrypt_all(oldp, newp); /* Now reencrypt all plugins passwords fields * FIXME: Unloaded plugins won't be able to update their stored passwords */ plugins_master_passphrase_change(oldp, newp); master_passphrase_forget(); }
static const gchar *master_passphrase() { gchar *input; gboolean end = FALSE; if (!prefs_common_get_prefs()->use_master_passphrase) { return PASSCRYPT_KEY; } if (_master_passphrase != NULL) { debug_print("Master passphrase is in memory, offering it.\n"); return _master_passphrase; } while (!end) { input = input_dialog_with_invisible(_("Input master passphrase"), _("Input master passphrase"), NULL); if (input == NULL) { debug_print("Cancel pressed at master passphrase dialog.\n"); break; } if (master_passphrase_is_correct(input)) { debug_print("Entered master passphrase seems to be correct, remembering it.\n"); _master_passphrase = input; end = TRUE; } else { alertpanel_error(_("Incorrect master passphrase.")); } } return _master_passphrase; }
static void notification_trayicon_on_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data) { MainWindow *mainwin = mainwindow_get_mainwindow(); if(!mainwin) return; /* tell callbacks to skip any event */ updating_menu = TRUE; /* initialize checkitems according to current states */ cm_toggle_menu_set_active("SysTrayiconPopup/ToggleOffline", prefs_common_get_prefs()->work_offline); #ifdef HAVE_LIBNOTIFY cm_toggle_menu_set_active("SysTrayiconPopup/ShowBubbles", notify_config.trayicon_popup_enabled); #endif cm_menu_set_sensitive("SysTrayiconPopup/GetMail", mainwin->lock_count == 0); updating_menu = FALSE; #ifndef G_OS_WIN32 gtk_menu_popup(GTK_MENU(traymenu_popup), NULL, NULL, NULL, NULL, button, activate_time); #else /* http://bugzilla.gnome.org/show_bug.cgi?id=552642 */ gtk_menu_popup(GTK_MENU(traymenu_popup), NULL, NULL, NULL, NULL, 0, activate_time); #endif }
static void _generate_salt() { guchar salt[KD_SALT_LENGTH]; if (prefs_common_get_prefs()->master_passphrase_salt != NULL) { g_free(prefs_common_get_prefs()->master_passphrase_salt); } if (!get_random_bytes(salt, KD_SALT_LENGTH)) { debug_print("Could not get random bytes for kd salt.\n"); return; } prefs_common_get_prefs()->master_passphrase_salt = g_base64_encode(salt, KD_SALT_LENGTH); }
static GtkWidget *p_create_frame_network(struct LibravatarPrefsPage *page) { GtkWidget *vbox, *chk_redirects, *spinner, *hbox; GtkAdjustment *adj; #if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0)) GtkWidget *chk_federated; #endif vbox = gtk_vbox_new(FALSE, 6); chk_redirects = create_checkbox(_("_Allow redirects to other sites"), _("Follow redirect responses received from " "libravatar server to other avatar " "services like gravatar.com")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_redirects), libravatarprefs.allow_redirects); page->allow_redirects_check = chk_redirects; gtk_box_pack_start(GTK_BOX(vbox), chk_redirects, FALSE, FALSE, 0); #if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0)) chk_federated = create_checkbox(_("_Enable federated servers"), _("Try to get avatar from sender's domain " "libravatar server")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_federated), libravatarprefs.allow_federated); page->allow_federated_check = chk_federated; gtk_box_pack_start(GTK_BOX(vbox), chk_federated, FALSE, FALSE, 0); #endif adj = (GtkAdjustment *) gtk_adjustment_new( libravatarprefs.timeout, TIMEOUT_MIN_S, (prefs_common_get_prefs()->io_timeout_secs > 0) ? (prefs_common_get_prefs()->io_timeout_secs - 1) : 0, 1.0, 0.0, 0.0); spinner = gtk_spin_button_new(adj, 1.0, 0); gtk_widget_show(spinner); hbox = labeled_spinner_box(_("Request timeout"), spinner, _("seconds"), _("Set to 0 to use global socket I/O timeout. " "Maximum value must be also less than global socket " "I/O timeout.")); page->timeout = spinner; gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); return vbox; }
static void trayicon_toggle_offline_cb(GtkAction *action, gpointer data) { /* toggle offline mode if menu checkitem has been clicked */ if(!updating_menu) { MainWindow *mainwin = mainwindow_get_mainwindow(); main_window_toggle_work_offline(mainwin, !prefs_common_get_prefs()->work_offline, TRUE); } }
static void app_exit_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { if(prefs_common_get_prefs()->confirm_on_exit) { if(alertpanel(_("Exit"), _("Exit Claws Mail?"), GTK_STOCK_CANCEL, GTK_STOCK_OK, NULL) != G_ALERTALTERNATE) { return; } manage_window_focus_in(mainwin->window, NULL, NULL); } if (prefs_common_get_prefs()->clean_on_exit) { if (!main_window_empty_trash(mainwin, prefs_common_get_prefs()->ask_on_clean, TRUE)) return; } app_will_exit(NULL, mainwin); }
const gboolean master_passphrase_is_correct(const gchar *input) { guchar *kd, *input_kd; gchar **tokens; gchar *stored_kd = prefs_common_get_prefs()->master_passphrase; gsize kd_len; guint rounds = 0; gint ret; g_return_val_if_fail(stored_kd != NULL && strlen(stored_kd) > 0, FALSE); g_return_val_if_fail(input != NULL, FALSE); if (stored_kd == NULL) return FALSE; tokens = g_strsplit_set(stored_kd, "{}", 3); if (tokens[0] == NULL || strlen(tokens[0]) != 0 || /* nothing before { */ tokens[1] == NULL || strncmp(tokens[1], "PBKDF2-HMAC-SHA1,", 17) || /* correct tag */ strlen(tokens[1]) <= 17 || /* something after , */ (rounds = atoi(tokens[1] + 17)) <= 0 || /* valid rounds # */ tokens[2] == NULL || strlen(tokens[2]) == 0) { /* string continues after } */ debug_print("Mangled master_passphrase format in config, can not use it.\n"); g_strfreev(tokens); return FALSE; } stored_kd = tokens[2]; kd = g_base64_decode(stored_kd, &kd_len); /* should be 64 */ g_strfreev(tokens); if (kd_len != KD_LENGTH) { debug_print("master_passphrase is %ld bytes long, should be %d.\n", kd_len, KD_LENGTH); g_free(kd); return FALSE; } input_kd = _make_key_deriv(input, rounds, KD_LENGTH); ret = memcmp(kd, input_kd, kd_len); g_free(input_kd); g_free(kd); if (ret == 0) return TRUE; return FALSE; }
static gboolean libravatar_image_render_hook(gpointer source, gpointer data) { AvatarRender *ar = (AvatarRender *)source; GtkWidget *image = NULL; gchar *a = NULL, *url = NULL; gchar md5sum[33]; debug_print("libravatar avatar_image_render invoked\n"); a = procmsg_msginfo_get_avatar(ar->full_msginfo, AVATAR_LIBRAVATAR); if (a != NULL) { gchar *base; md5_hex_digest(md5sum, a); /* try missing cache */ if (is_missing_md5(libravatarmisses, md5sum)) { return FALSE; } /* try disk cache */ image = image_widget_from_cached_md5(md5sum); if (image != NULL) { if (ar->image) /* previous plugin set one */ gtk_widget_destroy(ar->image); ar->image = image; ar->type = AVATAR_LIBRAVATAR; return FALSE; } /* not cached copy: try network */ if (prefs_common_get_prefs()->work_offline) { debug_print("working off-line: libravatar network retrieval skipped\n"); return FALSE; } base = federated_base_url_from_address(a); url = libravatar_url_for_md5(base, md5sum); if (url != NULL) { image = image_widget_from_url(url, md5sum); g_free(url); if (image != NULL) { if (ar->image) /* previous plugin set one */ gtk_widget_destroy(ar->image); ar->image = image; ar->type = AVATAR_LIBRAVATAR; } } g_free(base); return TRUE; } return FALSE; /* keep rendering */ }
gchar *password_encrypt_gnutls(const gchar *password, const gchar *encryption_passphrase) { /* Another, slightly inferior combination is AES-128-CBC + SHA-256. * Any block cipher in CBC mode with keysize N and a hash algo with * digest length 2*N would do. */ gnutls_cipher_algorithm_t algo = GNUTLS_CIPHER_AES_256_CBC; gnutls_cipher_hd_t handle; gnutls_datum_t key, iv; int keylen, blocklen, ret; unsigned char *buf, *encbuf, *base, *output; guint rounds = prefs_common_get_prefs()->master_passphrase_pbkdf2_rounds; g_return_val_if_fail(password != NULL, NULL); g_return_val_if_fail(encryption_passphrase != NULL, NULL); /* ivlen = gnutls_cipher_get_iv_size(algo);*/ keylen = gnutls_cipher_get_key_size(algo); blocklen = gnutls_cipher_get_block_size(algo); /* digestlen = gnutls_hash_get_len(digest); */ /* Take the passphrase and compute a key derivation of suitable * length to be used as encryption key for our block cipher. */ key.data = _make_key_deriv(encryption_passphrase, rounds, keylen); key.size = keylen; /* Prepare random IV for cipher */ iv.data = malloc(IVLEN); iv.size = IVLEN; if (!get_random_bytes(iv.data, IVLEN)) { g_free(key.data); g_free(iv.data); return NULL; } /* Initialize the encryption */ ret = gnutls_cipher_init(&handle, algo, &key, &iv); if (ret < 0) { g_free(key.data); g_free(iv.data); return NULL; } /* Fill buf with one block of random data, our password, pad the * rest with zero bytes. */ buf = malloc(BUFSIZE + blocklen); memset(buf, 0, BUFSIZE); if (!get_random_bytes(buf, blocklen)) { g_free(buf); g_free(key.data); g_free(iv.data); gnutls_cipher_deinit(handle); return NULL; } memcpy(buf + blocklen, password, strlen(password)); /* Encrypt into encbuf */ encbuf = malloc(BUFSIZE + blocklen); memset(encbuf, 0, BUFSIZE + blocklen); ret = gnutls_cipher_encrypt2(handle, buf, BUFSIZE + blocklen, encbuf, BUFSIZE + blocklen); if (ret < 0) { g_free(key.data); g_free(iv.data); g_free(buf); g_free(encbuf); gnutls_cipher_deinit(handle); return NULL; } /* Cleanup */ gnutls_cipher_deinit(handle); g_free(key.data); g_free(iv.data); g_free(buf); /* And finally prepare the resulting string: * "{algorithm,rounds}base64encodedciphertext" */ base = g_base64_encode(encbuf, BUFSIZE); g_free(encbuf); output = g_strdup_printf("{%s,%d}%s", gnutls_cipher_get_name(algo), rounds, base); g_free(base); return output; }
static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; MsgInfo *msginfo = mail_filtering_data->msginfo; GSList *msglist = mail_filtering_data->msglist; GSList *cur = NULL; static gboolean warned_error = FALSE; int status = 0; int total = 0, curnum = 0; GSList *new_hams = NULL, *new_spams = NULL; GSList *new_unsure, *whitelisted_new_spams = NULL; gchar *bogo_exec = (config.bogopath && *config.bogopath) ? config.bogopath:"bogofilter"; gchar *bogo_args[4]; gboolean ok_to_thread = TRUE; bogo_args[0] = bogo_exec; bogo_args[1] = "-T"; bogo_args[2] = "-b"; bogo_args[3] = NULL; if (!config.process_emails) { return FALSE; } if (msglist == NULL && msginfo != NULL) { g_warning("wrong call to bogofilter mail_filtering_hook"); return FALSE; } total = g_slist_length(msglist); /* we have to make sure the mails are cached - or it'll break on IMAP */ if (message_callback != NULL) message_callback(_("Bogofilter: fetching bodies..."), total, 0, FALSE); for (cur = msglist; cur; cur = cur->next) { gchar *file = procmsg_get_message_file((MsgInfo *)cur->data); if (file == NULL) ok_to_thread = FALSE; if (message_callback != NULL) message_callback(NULL, total, curnum++, FALSE); g_free(file); } if (message_callback != NULL) message_callback(NULL, 0, 0, FALSE); if (message_callback != NULL) message_callback(_("Bogofilter: filtering messages..."), total, 0, FALSE); #ifdef USE_PTHREAD while (pthread_mutex_trylock(&list_mutex) != 0) { GTK_EVENTS_FLUSH(); usleep(100); } #endif to_filter_data = g_new0(BogoFilterData, 1); to_filter_data->msglist = msglist; to_filter_data->mail_filtering_data = mail_filtering_data; to_filter_data->new_hams = NULL; to_filter_data->new_unsure = NULL; to_filter_data->new_spams = NULL; to_filter_data->whitelisted_new_spams = NULL; to_filter_data->done = FALSE; to_filter_data->status = -1; to_filter_data->bogo_args = bogo_args; #ifdef USE_PTHREAD to_filter_data->in_thread = (filter_th != 0 && ok_to_thread); #else to_filter_data->in_thread = FALSE; #endif #ifdef USE_PTHREAD pthread_mutex_unlock(&list_mutex); if (filter_th != 0 && ok_to_thread) { debug_print("waking thread to let it filter things\n"); pthread_mutex_lock(&wait_mutex); pthread_cond_broadcast(&wait_cond); pthread_mutex_unlock(&wait_mutex); while (!to_filter_data->done) { GTK_EVENTS_FLUSH(); usleep(100); } } while (pthread_mutex_trylock(&list_mutex) != 0) { GTK_EVENTS_FLUSH(); usleep(100); } if (filter_th == 0 || !ok_to_thread) bogofilter_do_filter(to_filter_data); #else bogofilter_do_filter(to_filter_data); #endif new_hams = to_filter_data->new_hams; new_unsure = to_filter_data->new_unsure; new_spams = to_filter_data->new_spams; whitelisted_new_spams = to_filter_data->whitelisted_new_spams; status = to_filter_data->status; g_free(to_filter_data); to_filter_data = NULL; #ifdef USE_PTHREAD pthread_mutex_unlock(&list_mutex); #endif /* unflag hams */ for (cur = new_hams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging ham: %d\n", msginfo->msgnum); } /* unflag unsure */ for (cur = new_unsure; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging unsure: %d\n", msginfo->msgnum); } if (config.learn_from_whitelist && whitelisted_new_spams) { /* flag whitelisted spams */ for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); debug_print("flagging whitelisted non-ham: %d\n", msginfo->msgnum); } /* correct bogo */ bogofilter_learn(NULL, whitelisted_new_spams, FALSE); /* unflag them */ for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("unflagging whitelisted non-ham: %d\n", msginfo->msgnum); } } else { for (cur = whitelisted_new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); debug_print("not flagging whitelisted non-ham: %d\n", msginfo->msgnum); } } /* flag spams and delete them if config.receive_spam == 0 * (if config.receive_spam is set to 1, we'll move them later, * mark as spam only if set to 2) */ for (cur = new_spams; cur; cur = cur->next) { MsgInfo *msginfo = (MsgInfo *)cur->data; if (config.receive_spam != SPAM_DELETE) { if (config.mark_as_read) procmsg_msginfo_unset_flags(msginfo, ~0, 0); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); } else { folder_item_remove_msg(msginfo->folder, msginfo->msgnum); } } if (status < 0 || status > 2) { /* I/O or other errors */ gchar *msg = NULL; if (status == 3) msg = g_strdup_printf(_("The Bogofilter plugin couldn't filter " "a message. The probable cause of the " "error is that it didn't learn from any mail.\n" "Use \"/Mark/Mark as spam\" and \"/Mark/Mark as " "ham\" to train Bogofilter with a few hundred " "spam and ham messages.")); else msg = g_strdup_printf(_("The Bogofilter plugin couldn't filter " "a message. The command `%s %s %s` couldn't be run."), bogo_args[0], bogo_args[1], bogo_args[2]); if (!prefs_common_get_prefs()->no_recv_err_panel) { if (!warned_error) { alertpanel_error("%s", msg); } warned_error = TRUE; } else { log_error(LOG_PROTOCOL, "%s\n", msg); } g_free(msg); } if (status < 0 || status > 2) { g_slist_free(mail_filtering_data->filtered); g_slist_free(mail_filtering_data->unfiltered); mail_filtering_data->filtered = NULL; mail_filtering_data->unfiltered = NULL; } else { if (config.receive_spam == SPAM_MARK_AND_SAVE && new_spams) { FolderItem *save_folder = NULL; if ((!config.save_folder) || (config.save_folder[0] == '\0') || ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL)) { if (mail_filtering_data->account && mail_filtering_data->account->set_trash_folder) { save_folder = folder_find_item_from_identifier( mail_filtering_data->account->trash_folder); if (save_folder) debug_print("found trash folder from account's advanced settings\n"); } if (save_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) { save_folder = mail_filtering_data->account->folder->trash; if (save_folder) debug_print("found trash folder from account's trash\n"); } if (save_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's inbox\n"); } } if (!save_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's local_inbox\n"); } } } if (save_folder == NULL) { debug_print("using default trash folder\n"); save_folder = folder_get_default_trash(); } } if (save_folder) { for (cur = new_spams; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_folder; } } } if (config.save_unsure && new_unsure) { FolderItem *save_unsure_folder = NULL; if ((!config.save_unsure_folder) || (config.save_unsure_folder[0] == '\0') || ((save_unsure_folder = folder_find_item_from_identifier(config.save_unsure_folder)) == NULL)) { if (mail_filtering_data->account) save_unsure_folder = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (save_unsure_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) save_unsure_folder = mail_filtering_data->account->folder->inbox; if (save_unsure_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item) { save_unsure_folder = item; } } if (!save_unsure_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item) { save_unsure_folder = item; } } } if (save_unsure_folder == NULL) save_unsure_folder = folder_get_default_inbox(); } if (save_unsure_folder) { for (cur = new_unsure; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_unsure_folder; } } } } g_slist_free(new_hams); g_slist_free(new_unsure); g_slist_free(new_spams); g_slist_free(whitelisted_new_spams); if (message_callback != NULL) message_callback(NULL, 0, 0, FALSE); mail_filtering_data->filtered = g_slist_reverse( mail_filtering_data->filtered); mail_filtering_data->unfiltered = g_slist_reverse( mail_filtering_data->unfiltered); return FALSE; }
static GtkWidget *image_widget_from_url(const gchar *url, const gchar *md5) { GtkWidget *image = NULL; gchar *filename; FILE *file; CURL *curl; curl = curl_easy_init(); if (curl == NULL) { g_warning("could not initialize curl to get image from URL"); return NULL; } curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_image_data_cb); /* make sure timeout is less than general IO timeout */ curl_easy_setopt(curl, CURLOPT_TIMEOUT, (libravatarprefs.timeout == 0 || libravatarprefs.timeout > prefs_common_get_prefs()->io_timeout_secs) ? prefs_common_get_prefs()->io_timeout_secs : libravatarprefs.timeout); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); filename = cache_name_for_md5(md5); file = fopen(filename, "wb"); if (file != NULL) { long filesize; if (libravatarprefs.allow_redirects) { long maxredirs = (libravatarprefs.default_mode == DEF_MODE_URL)? 3L : ((libravatarprefs.default_mode == DEF_MODE_MM)? 2L: 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, maxredirs); } curl_easy_setopt(curl, CURLOPT_FILE, file); debug_print("retrieving URL to file: %s -> %s\n", url, filename); curl_easy_perform(curl); filesize = ftell(file); fclose(file); if (filesize < MIN_PNG_SIZE) debug_print("not enough data for an avatar image: %ld bytes\n", filesize); else image = image_widget_from_filename(filename); if (!libravatarprefs.cache_icons || filesize == 0) { if (g_unlink(filename) < 0) g_warning("failed to delete cache file '%s'", filename); } if (filesize == 0) missing_add_md5(libravatarmisses, md5); } else { g_warning("could not open '%s' for writing", filename); } curl_easy_cleanup(curl); g_free(filename); return image; }
gchar *sgpgme_sigstat_info_full(gpgme_ctx_t ctx, gpgme_verify_result_t status) { gint i = 0; gchar *ret; GString *siginfo; gpgme_signature_t sig = NULL; siginfo = g_string_sized_new(64); if (status == NULL) { g_string_append_printf(siginfo, _("Error checking signature: no status\n")); goto bail; } sig = status->signatures; while (sig) { char buf[100]; struct tm lt; gpgme_user_id_t user = NULL; gpgme_key_t key; gpgme_error_t err; const gchar *keytype, *keyid, *uid; err = gpgme_get_key(ctx, sig->fpr, &key, 0); if (err != GPG_ERR_NO_ERROR) { key = NULL; g_string_append_printf(siginfo, _("Error checking signature: %s\n"), gpgme_strerror(err)); goto bail; } if (key) { user = key->uids; keytype = gpgme_pubkey_algo_name( key->subkeys->pubkey_algo); keyid = key->subkeys->keyid; uid = user->uid; } else { keytype = "?"; keyid = "?"; uid = "?"; } memset(buf, 0, sizeof(buf)); fast_strftime(buf, sizeof(buf)-1, prefs_common_get_prefs()->date_format, localtime_r(&sig->timestamp, <)); g_string_append_printf(siginfo, _("Signature made on %s using %s key ID %s\n"), buf, keytype, keyid); switch (gpg_err_code(sig->status)) { case GPG_ERR_NO_ERROR: g_string_append_printf(siginfo, _("Good signature from uid \"%s\" (Validity: %s)\n"), uid, get_validity_str(user?user->validity:GPGME_VALIDITY_UNKNOWN)); break; case GPG_ERR_KEY_EXPIRED: g_string_append_printf(siginfo, _("Expired key uid \"%s\"\n"), uid); break; case GPG_ERR_SIG_EXPIRED: g_string_append_printf(siginfo, _("Expired signature from uid \"%s\" (Validity: %s)\n"), uid, get_validity_str(user?user->validity:GPGME_VALIDITY_UNKNOWN)); break; case GPG_ERR_CERT_REVOKED: g_string_append_printf(siginfo, _("Revoked key uid \"%s\"\n"), uid); break; case GPG_ERR_BAD_SIGNATURE: g_string_append_printf(siginfo, _("BAD signature from \"%s\"\n"), uid); break; default: break; } if (sig->status != GPG_ERR_BAD_SIGNATURE) { gint j = 1; user = user ? user->next : NULL; while (user != NULL) { g_string_append_printf(siginfo, _(" uid \"%s\" (Validity: %s)\n"), user->uid, user->revoked==TRUE?_("Revoked"):get_validity_str(user->validity)); j++; user = user->next; } g_string_append_printf(siginfo,_("Owner Trust: %s\n"), get_owner_trust_str(key->owner_trust)); g_string_append(siginfo, _("Primary key fingerprint:")); const char* primary_fpr = NULL; if (key && key->subkeys && key->subkeys->fpr) primary_fpr = key->subkeys->fpr; else g_string_append(siginfo, " ?"); int idx; /* now pretty-print the fingerprint */ for (idx=0; primary_fpr && *primary_fpr!='\0'; idx++, primary_fpr++) { if (idx%4==0) g_string_append_c(siginfo, ' '); if (idx%20==0) g_string_append_c(siginfo, ' '); g_string_append_c(siginfo, (gchar)*primary_fpr); } g_string_append_c(siginfo, '\n'); #ifdef HAVE_GPGME_PKA_TRUST if (sig->pka_trust == 1 && sig->pka_address) { g_string_append_printf(siginfo, _("WARNING: Signer's address \"%s\" " "does not match DNS entry\n"), sig->pka_address); } else if (sig->pka_trust == 2 && sig->pka_address) { g_string_append_printf(siginfo, _("Verified signer's address is \"%s\"\n"), sig->pka_address); /* FIXME: Compare the address to the * From: address. */ } #endif /*HAVE_GPGME_PKA_TRUST*/ } g_string_append(siginfo, "\n"); i++; sig = sig->next; } bail: ret = siginfo->str; g_string_free(siginfo, FALSE); return ret; }
static GtkWidget *p_create_frame_missing(struct LibravatarPrefsPage *page) { GtkWidget *vbox, *radio[NUM_DEF_BUTTONS], *hbox, *entry; gboolean enable = FALSE; int i, e = 0; gchar *radio_label[] = { _("None"), _("Mystery man"), _("Identicon"), _("MonsterID"), _("Wavatar"), _("Retro"), _("Custom URL") }; gchar *radio_hint[] = { _("A blank image"), _("The unobtrusive low-contrast greyish silhouette"), _("A generated geometric pattern"), _("A generated full-body monster"), _("A generated almost unique face"), _("A generated 8-bit arcade-style pixelated image"), _("Redirect to a user provided URL") }; vbox = gtk_vbox_new(FALSE, 6); for (i = 0; i < NUM_DEF_BUTTONS; ++i) { enable = (libravatarprefs.default_mode == radio_value[i])? TRUE: FALSE; e += enable? 1: 0; radio[i] = gtk_radio_button_new_with_label_from_widget( (i > 0)? GTK_RADIO_BUTTON(radio[i - 1]): NULL, radio_label[i]); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio[i]), enable); if (i == CUSTOM_URL_BUTTON_INDEX) { /* set related entry next to radio button */ entry = gtk_entry_new_with_max_length(MAX_URL_LENGTH); CLAWS_SET_TIP(entry, _("Enter the URL you want to be " "redirected when no user icon is available. " "Leave an empty URL to use the default " "libravatar orange icon.")); gtk_widget_show(entry); gtk_entry_set_text(GTK_ENTRY(entry), libravatarprefs.default_mode_url); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(hbox), radio[i], FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); gtk_widget_set_sensitive(entry, (libravatarprefs.default_mode == DEF_MODE_URL) ? TRUE: FALSE); page->defm_url_text = entry; gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); } else { gtk_box_pack_start(GTK_BOX(vbox), radio[i], FALSE, FALSE, 0); } g_signal_connect(radio[i], "toggled", G_CALLBACK(default_mode_radio_button_cb), (gpointer) &(radio_value[i])); CLAWS_SET_TIP(radio[i], radio_hint[i]); gtk_widget_show(radio[i]); page->defm_radio[i] = radio[i]; } if (e == 0) { /* unknown value, go default */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio[0]), TRUE); libravatarprefs.default_mode = DEF_MODE_NONE; } /* don't waste time with headers that won't be displayed */ prefs_common_get_prefs()->enable_avatars = (libravatarprefs.default_mode == DEF_MODE_NONE) ? AVATARS_ENABLE_BOTH: AVATARS_DISABLE; return vbox; }
static void pgpview_show_mime_part(TextView *textview, MimeInfo *partinfo) { GtkTextView *text; GtkTextBuffer *buffer; GtkTextIter iter; gpgme_data_t sigdata = NULL; gpgme_verify_result_t sigstatus = NULL; gpgme_ctx_t ctx = NULL; gpgme_key_t key = NULL; gpgme_signature_t sig = NULL; gpgme_error_t err = 0; gboolean imported = FALSE; if (!partinfo) return; textview_set_font(textview, NULL); textview_clear(textview); text = GTK_TEXT_VIEW(textview->text); buffer = gtk_text_view_get_buffer(text); gtk_text_buffer_get_start_iter(buffer, &iter); err = gpgme_new (&ctx); if (err) { debug_print("err : %s\n", gpgme_strerror(err)); textview_show_mime_part(textview, partinfo); return; } sigdata = sgpgme_data_from_mimeinfo(partinfo); if (!sigdata) { g_warning("no sigdata"); textview_show_mime_part(textview, partinfo); return; } /* Here we do not care about what data we attempt to verify with the * signature, or about result of the verification - all we care about * is that we find out ID of the key used to make this signature. */ sigstatus = sgpgme_verify_signature(ctx, sigdata, NULL, sigdata); if (!sigstatus || sigstatus == GINT_TO_POINTER(-GPG_ERR_SYSTEM_ERROR)) { g_warning("no sigstatus"); textview_show_mime_part(textview, partinfo); return; } sig = sigstatus->signatures; if (!sig) { g_warning("no sig"); textview_show_mime_part(textview, partinfo); return; } gpgme_get_key(ctx, sig->fpr, &key, 0); if (!key) { gchar *gpgbin = get_gpg_executable_name(); gchar *cmd = g_strdup_printf("\"%s\" --batch --no-tty --recv-keys %s", (gpgbin ? gpgbin : "gpg"), sig->fpr); AlertValue val = G_ALERTDEFAULT; if (!prefs_common_get_prefs()->work_offline) { val = alertpanel(_("Key import"), _("This key is not in your keyring. Do you want " "Claws Mail to try and import it from a " "keyserver?"), GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND); GTK_EVENTS_FLUSH(); } if (val == G_ALERTDEFAULT) { TEXTVIEW_INSERT(_("\n Key ID ")); TEXTVIEW_INSERT(sig->fpr); TEXTVIEW_INSERT(":\n\n"); TEXTVIEW_INSERT(_(" This key is not in your keyring.\n")); TEXTVIEW_INSERT(_(" It should be possible to import it ")); if (prefs_common_get_prefs()->work_offline) TEXTVIEW_INSERT(_("when working online,\n or ")); TEXTVIEW_INSERT(_("with the following command: \n\n ")); TEXTVIEW_INSERT(cmd); } else { TEXTVIEW_INSERT(_("\n Importing key ID ")); TEXTVIEW_INSERT(sig->fpr); TEXTVIEW_INSERT(":\n\n"); main_window_cursor_wait(mainwindow_get_mainwindow()); textview_cursor_wait(textview); GTK_EVENTS_FLUSH(); #ifndef G_OS_WIN32 int res = 0; pid_t pid = 0; pid = fork(); if (pid == -1) { res = -1; } else if (pid == 0) { /* son */ gchar **argv; argv = strsplit_with_quote(cmd, " ", 0); res = execvp(argv[0], argv); perror("execvp"); exit(255); } else { int status = 0; time_t start_wait = time(NULL); res = -1; do { if (waitpid(pid, &status, WNOHANG) == 0 || !WIFEXITED(status)) { usleep(200000); } else { res = WEXITSTATUS(status); break; } if (time(NULL) - start_wait > 9) { debug_print("SIGTERM'ing gpg %d\n", pid); kill(pid, SIGTERM); } if (time(NULL) - start_wait > 10) { debug_print("SIGKILL'ing gpg %d\n", pid); kill(pid, SIGKILL); break; } } while(1); } debug_print("res %d\n", res); if (res == 0) imported = TRUE; #else /* We need to call gpg in a separate thread, so that waiting for * it to finish does not block the UI. */ pthread_t pt; struct _ImportCtx *ctx = malloc(sizeof(struct _ImportCtx)); ctx->done = FALSE; ctx->exitcode = STILL_ACTIVE; ctx->cmd = cmd; if (pthread_create(&pt, NULL, _import_threaded, (void *)ctx) != 0) { debug_print("Couldn't create thread, continuing unthreaded.\n"); _import_threaded(ctx); } else { debug_print("Thread created, waiting for it to finish...\n"); while (!ctx->done) claws_do_idle(); } debug_print("Thread finished.\n"); pthread_join(pt, NULL); if (ctx->exitcode == 0) { imported = TRUE; } g_free(ctx); #endif main_window_cursor_normal(mainwindow_get_mainwindow()); textview_cursor_normal(textview); if (imported) { TEXTVIEW_INSERT(_(" This key has been imported to your keyring.\n")); } else { TEXTVIEW_INSERT(_(" This key couldn't be imported to your keyring.\n")); TEXTVIEW_INSERT(_(" Key servers are sometimes slow.\n")); TEXTVIEW_INSERT(_(" You can try to import it manually with the command:\n\n ")); TEXTVIEW_INSERT(cmd); } } g_free(cmd); return; } else { TEXTVIEW_INSERT(_("\n Key ID ")); #if defined GPGME_VERSION_NUMBER && GPGME_VERSION_NUMBER >= 0x010700 TEXTVIEW_INSERT(key->fpr); #else TEXTVIEW_INSERT(sig->fpr); #endif TEXTVIEW_INSERT(":\n\n"); TEXTVIEW_INSERT(_(" This key is in your keyring.\n")); } gpgme_data_release(sigdata); gpgme_release(ctx); textview_show_icon(textview, GTK_STOCK_DIALOG_AUTHENTICATION); }
int spamassassin_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam) { gchar *cmd = NULL; gchar *file = NULL; const gchar *shell = g_getenv("SHELL"); gchar *spamc_wrapper = NULL; if (msginfo == NULL && msglist == NULL) { return -1; } if (config.transport == SPAMASSASSIN_TRANSPORT_TCP && prefs_common_get_prefs()->work_offline && !inc_offline_should_override(TRUE, _("Claws Mail needs network access in order " "to feed the mail to the remote learner."))) { return -1; } if (msginfo) { file = procmsg_get_message_file(msginfo); if (file == NULL) { return -1; } if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) { spamc_wrapper = spamassassin_create_tmp_spamc_wrapper(spam); if (spamc_wrapper != NULL) { cmd = g_strconcat(shell?shell:"sh", " ", spamc_wrapper, " ", file, NULL); } } else { cmd = g_strdup_printf("sa-learn -u %s%s %s %s", config.username, prefs_common_get_prefs()->work_offline?" -L":"", spam?"--spam":"--ham", file); } } if (msglist) { GSList *cur = msglist; MsgInfo *info; if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) { /* execute n-times the spamc command */ for (; cur; cur = cur->next) { info = (MsgInfo *)cur->data; gchar *tmpcmd = NULL; gchar *tmpfile = get_tmp_file(); if (spamc_wrapper == NULL) { spamc_wrapper = spamassassin_create_tmp_spamc_wrapper(spam); } if (spamc_wrapper && tmpfile && copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) { tmpcmd = g_strconcat(shell?shell:"sh", " ", spamc_wrapper, " ", tmpfile, NULL); debug_print("%s\n", tmpcmd); execute_command_line(tmpcmd, FALSE, NULL); g_free(tmpcmd); } g_free(tmpfile); } g_free(spamc_wrapper); return 0; } else { cmd = g_strdup_printf("sa-learn -u %s%s %s", config.username, prefs_common_get_prefs()->work_offline?" -L":"", spam?"--spam":"--ham"); /* concatenate all message tmpfiles to the sa-learn command-line */ for (; cur; cur = cur->next) { info = (MsgInfo *)cur->data; gchar *tmpcmd = NULL; gchar *tmpfile = get_tmp_file(); if (tmpfile && copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) { tmpcmd = g_strconcat(cmd, " ", tmpfile, NULL); g_free(cmd); cmd = tmpcmd; } g_free(tmpfile); } } } if (cmd == NULL) { return -1; } debug_print("%s\n", cmd); /* only run sync calls to sa-learn/spamc to prevent system lockdown */ execute_command_line(cmd, FALSE, NULL); g_free(cmd); g_free(spamc_wrapper); return 0; }
/* Create the window for selecting folders with checkboxes */ static void foldercheck_create_window(SpecificFolderArrayEntry *entry) { GtkWidget *vbox; GtkWidget *scrolledwin; GtkWidget *confirm_area; GtkWidget *checkbox; GtkWidget *cancel_button; GtkWidget *ok_button; GtkTreeSelection *selection; GtkTreeViewColumn *column; GtkCellRenderer *renderer; static GdkGeometry geometry; /* Create window */ entry->window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "notification_foldercheck"); gtk_window_set_title(GTK_WINDOW(entry->window), _("Select folder(s)")); gtk_container_set_border_width(GTK_CONTAINER(entry->window), 4); gtk_window_set_position(GTK_WINDOW(entry->window), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(entry->window), TRUE); gtk_window_set_resizable(GTK_WINDOW(entry->window), TRUE); gtk_window_set_wmclass (GTK_WINDOW(entry->window), "folder_selection", "Claws Mail"); g_signal_connect(G_OBJECT(entry->window), "delete_event", G_CALLBACK(delete_event), entry); g_signal_connect(G_OBJECT(entry->window), "key_press_event", G_CALLBACK(key_pressed), entry); MANAGE_WINDOW_SIGNALS_CONNECT(entry->window); /* vbox */ vbox = gtk_vbox_new(FALSE, 4); gtk_container_add(GTK_CONTAINER(entry->window), vbox); /* scrolled window */ scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0); /* pixbufs */ if(!folder_pixbuf) stock_pixbuf_gdk(STOCK_PIXMAP_DIR_CLOSE, &folder_pixbuf); if(!folderopen_pixbuf) stock_pixbuf_gdk(STOCK_PIXMAP_DIR_OPEN, &folderopen_pixbuf); if(!foldernoselect_pixbuf) stock_pixbuf_gdk(STOCK_PIXMAP_DIR_NOSELECT_CLOSE, &foldernoselect_pixbuf); if(!foldernoselectopen_pixbuf) stock_pixbuf_gdk(STOCK_PIXMAP_DIR_NOSELECT_OPEN, &foldernoselectopen_pixbuf); /* Tree store */ foldercheck_set_tree(entry); gtk_tree_model_foreach(GTK_TREE_MODEL(entry->tree_store), foldercheck_foreach_update_to_list, entry); /* tree view */ entry->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(entry->tree_store)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(entry->treeview), FALSE); gtk_tree_view_set_search_column(GTK_TREE_VIEW(entry->treeview), FOLDERCHECK_FOLDERNAME); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(entry->treeview), prefs_common_get_prefs()->use_stripes_everywhere); gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(entry->treeview), FALSE); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(entry->treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); gtk_tree_selection_set_select_function(selection, foldercheck_selected, NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolledwin), entry->treeview); /* --- column 1 --- */ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, "sel"); gtk_tree_view_column_set_spacing(column, 2); /* checkbox */ renderer = gtk_cell_renderer_toggle_new(); g_object_set(renderer, "xalign", 0.0, NULL); gtk_tree_view_column_pack_start(column, renderer, TRUE); g_signal_connect(renderer, "toggled", G_CALLBACK(folder_toggle_cb),entry); gtk_tree_view_column_set_attributes(column, renderer, "active", FOLDERCHECK_CHECK,NULL); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_append_column(GTK_TREE_VIEW(entry->treeview), column); /* --- column 2 --- */ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(column, "Folder"); gtk_tree_view_column_set_spacing(column, 2); /* pixbuf */ renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", FOLDERCHECK_PIXBUF, "pixbuf-expander-open", FOLDERCHECK_PIXBUF_OPEN, "pixbuf-expander-closed", FOLDERCHECK_PIXBUF, NULL); /* text */ renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_set_attributes(column, renderer, "text", FOLDERCHECK_FOLDERNAME, NULL); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_append_column(GTK_TREE_VIEW(entry->treeview), column); /* recursive */ checkbox = gtk_check_button_new_with_label( _("select recursively")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), FALSE); g_signal_connect(G_OBJECT(checkbox), "toggled", G_CALLBACK(foldercheck_recursive_cb), entry); gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 10); gtkut_stock_button_set_create(&confirm_area, &cancel_button, GTK_STOCK_CANCEL, &ok_button, GTK_STOCK_OK, NULL, NULL); gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0); gtk_widget_grab_default(ok_button); g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(foldercheck_ok), entry); g_signal_connect(G_OBJECT(cancel_button), "clicked", G_CALLBACK(foldercheck_cancel), entry); if(!geometry.min_height) { geometry.min_width = 360; geometry.min_height = 360; } gtk_window_set_geometry_hints(GTK_WINDOW(entry->window), NULL, &geometry, GDK_HINT_MIN_SIZE); gtk_tree_view_expand_all(GTK_TREE_VIEW(entry->treeview)); gtk_widget_show_all(vbox); }
void notification_update_trayicon() { gchar *buf; static GdkPixbuf *old_icon = NULL; GdkPixbuf *new_icon; gint offset; NotificationMsgCount count; GSList *list; if(!notify_config.trayicon_enabled) return; if(notify_config.trayicon_folder_specific) { guint id; id = notification_register_folder_specific_list (TRAYICON_SPECIFIC_FOLDER_ID_STR); list = notification_foldercheck_get_list(id); } else list = NULL; notification_core_get_msg_count(list, &count); if(!trayicon) { #ifdef NOTIFICATION_HOTKEYS notification_hotkeys_update_bindings(); #endif old_icon = notification_trayicon_create(); if(!trayicon) { debug_print("Notification plugin: Could not create trayicon\n"); return; } } /* Tooltip */ buf = g_strdup_printf(_("New %d, Unread: %d, Total: %d"), count.new_msgs, count.unread_msgs, count.total_msgs); #if GTK_CHECK_VERSION(2,16,0) gtk_status_icon_set_tooltip_text(trayicon, buf); #else gtk_status_icon_set_tooltip(trayicon, buf); #endif g_free(buf); /* Pixmap */ (prefs_common_get_prefs()->work_offline) ? (offset = 1) : (offset = 0); if((count.new_msgs > 0) && (count.unreadmarked_msgs > 0)) new_icon = notification_pixbuf_get(NOTIFICATION_TRAYICON_NEWMARKEDMAIL+offset); else if(count.new_msgs > 0) new_icon = notification_pixbuf_get(NOTIFICATION_TRAYICON_NEWMAIL+offset); else if(count.unreadmarked_msgs > 0) new_icon = notification_pixbuf_get(NOTIFICATION_TRAYICON_UNREADMARKEDMAIL+offset); else if(count.unread_msgs > 0) new_icon = notification_pixbuf_get(NOTIFICATION_TRAYICON_UNREADMAIL+offset); else new_icon = notification_pixbuf_get(NOTIFICATION_TRAYICON_NOMAIL+offset); if(new_icon != old_icon) { gtk_status_icon_set_from_pixbuf(trayicon, new_icon); old_icon = new_icon; } }
static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; MsgInfo *msginfo = mail_filtering_data->msginfo; gboolean is_spam = FALSE, error = FALSE; static gboolean warned_error = FALSE; FILE *fp = NULL; int pid = 0; int status; /* SPAMASSASSIN_DISABLED : keep test for compatibility purpose */ if (!config.enable || config.transport == SPAMASSASSIN_DISABLED) { log_warning(LOG_PROTOCOL, _("SpamAssassin plugin is disabled by its preferences.\n")); return FALSE; } debug_print("Filtering message %d\n", msginfo->msgnum); if (message_callback != NULL) message_callback(_("SpamAssassin: filtering message...")); if ((fp = procmsg_open_message(msginfo)) == NULL) { debug_print("failed to open message file\n"); return FALSE; } if (config.whitelist_ab) { gchar *ab_folderpath; gboolean whitelisted = FALSE; if (*config.whitelist_ab_folder == '\0' || strcasecmp(config.whitelist_ab_folder, "Any") == 0) { /* match the whole addressbook */ ab_folderpath = NULL; } else { /* match the specific book/folder of the addressbook */ ab_folderpath = config.whitelist_ab_folder; } start_address_completion(ab_folderpath); if (msginfo->from && sa_found_in_addressbook(msginfo->from)) whitelisted = TRUE; end_address_completion(); if (whitelisted) { debug_print("message is ham (whitelisted)\n"); fclose(fp); return FALSE; } } pid = fork(); if (pid == 0) { _exit(msg_is_spam(fp)); } else { gint running = 0; running |= CHILD_RUNNING; g_timeout_add(50, timeout_func, &running); running |= TIMEOUT_RUNNING; while(running & CHILD_RUNNING) { int ret; ret = waitpid(pid, &status, WNOHANG); if (ret == pid) { if (WIFEXITED(status)) { MsgStatus result = MSG_IS_HAM; running &= ~CHILD_RUNNING; result = WEXITSTATUS(status); is_spam = (result == MSG_IS_SPAM) ? TRUE : FALSE; error = (result == MSG_FILTERING_ERROR); } } if (ret < 0) { running &= ~CHILD_RUNNING; } /* ret == 0 continue */ g_main_context_iteration(NULL, TRUE); } while (running & TIMEOUT_RUNNING) g_main_context_iteration(NULL, TRUE); } fclose(fp); if (is_spam) { debug_print("message is spam\n"); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); if (config.receive_spam) { FolderItem *save_folder = NULL; if ((!config.save_folder) || (config.save_folder[0] == '\0') || ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL)) { if (mail_filtering_data->account && mail_filtering_data->account->set_trash_folder) { save_folder = folder_find_item_from_identifier( mail_filtering_data->account->trash_folder); if (save_folder) debug_print("found trash folder from account's advanced settings\n"); } if (save_folder == NULL && mail_filtering_data->account && mail_filtering_data->account->folder) { save_folder = mail_filtering_data->account->folder->trash; if (save_folder) debug_print("found trash folder from account's trash\n"); } if (save_folder == NULL && mail_filtering_data->account && !mail_filtering_data->account->folder) { if (mail_filtering_data->account->inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's inbox\n"); } } if (!save_folder && mail_filtering_data->account->local_inbox) { FolderItem *item = folder_find_item_from_identifier( mail_filtering_data->account->local_inbox); if (item && item->folder->trash) { save_folder = item->folder->trash; debug_print("found trash folder from account's local_inbox\n"); } } } if (save_folder == NULL) { debug_print("using default trash folder\n"); save_folder = folder_get_default_trash(); } } if (config.mark_as_read) procmsg_msginfo_unset_flags(msginfo, ~0, 0); procmsg_msginfo_set_flags(msginfo, MSG_SPAM, 0); msginfo->filter_op = IS_MOVE; msginfo->to_filter_folder = save_folder; } else { folder_item_remove_msg(msginfo->folder, msginfo->msgnum); } return TRUE; } else { debug_print("message is ham\n"); procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0); } if (error) { gchar *msg = _("The SpamAssassin plugin couldn't filter " "a message. The probable cause of the error " "is an unreachable spamd daemon. Please make " "sure spamd is running and accessible."); if (!prefs_common_get_prefs()->no_recv_err_panel) { if (!warned_error) { alertpanel_error("%s", msg); } warned_error = TRUE; } else { log_error(LOG_PROTOCOL, "%s\n", msg); } } return FALSE; }
static gboolean scan_func(GNode *node, gpointer data) { struct clamd_result *result = (struct clamd_result *) data; MimeInfo *mimeinfo = (MimeInfo *) node->data; gchar *outfile; response buf; int max; GStatBuf info; gchar* msg; outfile = procmime_get_tmp_file_name(mimeinfo); if (procmime_get_part(outfile, mimeinfo) < 0) g_warning("Can't get the part of multipart message."); else { max = config.clamav_max_size * 1048576; /* maximum file size */ if (g_stat(outfile, &info) == -1) g_warning("Can't determine file size"); else { if (info.st_size <= max) { debug_print("Scanning %s\n", outfile); result->status = clamd_verify_email(outfile, &buf); debug_print("status: %d\n", result->status); switch (result->status) { case NO_SOCKET: g_warning("[scanning] No socket information"); if (config.alert_ack) { alertpanel_error(_("Scanning\nNo socket information.\nAntivirus disabled.")); config.alert_ack = FALSE; } break; case NO_CONNECTION: g_warning("[scanning] Clamd does not respond to ping"); if (config.alert_ack) { alertpanel_warning(_("Scanning\nClamd does not respond to ping.\nIs clamd running?")); config.alert_ack = FALSE; } break; case VIRUS: msg = g_strconcat(_("Detected %s virus."), clamd_get_virus_name(buf.msg), NULL); g_warning("%s\n", msg); debug_print("no_recv: %d\n", prefs_common_get_prefs()->no_recv_err_panel); if (prefs_common_get_prefs()->no_recv_err_panel) { statusbar_print_all("%s", msg); } else { alertpanel_warning("%s\n", msg); } g_free(msg); config.alert_ack = TRUE; break; case SCAN_ERROR: debug_print("Error: %s\n", buf.msg); if (config.alert_ack) { alertpanel_error(_("Scanning error:\n%s"), buf.msg); config.alert_ack = FALSE; } break; case OK: debug_print("No virus detected.\n"); config.alert_ack = TRUE; break; } } else { msg = g_strdup_printf(_("File: %s. Size (%d) greater than limit (%d)\n"), outfile, (int) info.st_size, max); statusbar_print_all("%s", msg); debug_print("%s", msg); g_free(msg); } } g_unlink(outfile); } return (result->status == OK) ? FALSE : TRUE; }