static void sieve_session_reset(SieveSession *session) { PrefsAccount *account = session->account; SieveAccountConfig *config = sieve_prefs_account_get_config(account); gboolean reuse_auth = (config->auth == SIEVEAUTH_REUSE); g_slist_free_full(session->send_queue, (GDestroyNotify)command_abort); session_disconnect(SESSION(session)); SESSION(session)->ssl_cert_auto_accept = account->ssl_certs_auto_accept; SESSION(session)->nonblocking = account->use_nonblocking_ssl; session->authenticated = FALSE; session->current_cmd = NULL; session->send_queue = NULL; session->state = SIEVE_CAPABILITIES; #ifdef USE_GNUTLS session->tls_init_done = FALSE; #endif session->avail_auth_type = 0; session->auth_type = 0; session->config = config; session->host = config->use_host ? config->host : account->recv_server; session->port = config->use_port ? config->port : SIEVE_PORT; session->user = reuse_auth ? account->userid : session->config->userid; session->forced_auth_type = config->auth_type; session_register_ping(SESSION(session), sieve_ping); if (session->pass) g_free(session->pass); if (config->auth == SIEVEAUTH_NONE) { session->pass = NULL; } else if (reuse_auth && account->passwd) { session->pass = g_strdup(account->passwd); } else if (config->passwd && config->passwd[0]) { session->pass = g_strdup(config->passwd); } else if (password_get(session->user, session->host, "sieve", session->port, &session->pass)) { } else { session->pass = input_dialog_query_password_keep(session->host, session->user, &(session->pass)); } if (!session->pass) { session->pass = g_strdup(""); session->use_auth = FALSE; } else { session->use_auth = TRUE; } #ifdef USE_GNUTLS SESSION(session)->ssl_type = (config->tls_type == SIEVE_TLS_NO) ? SSL_NONE : SSL_STARTTLS; #endif }
static gint inc_start(IncProgressDialog *inc_dialog) { IncSession *session; GList *qlist; Pop3Session *pop3_session; IncState inc_state; gint error_num = 0; gint new_msgs = 0; gchar *msg; gchar *fin_msg; FolderItem *processing, *inbox; GSList *msglist, *msglist_element; gboolean cancelled = FALSE; qlist = inc_dialog->queue_list; while (qlist != NULL) { GList *next = qlist->next; session = qlist->data; pop3_session = POP3_SESSION(session->session); pop3_session->user = g_strdup(pop3_session->ac_prefs->userid); if (inc_dialog->show_dialog) manage_window_focus_in (inc_dialog->dialog->window, NULL, NULL); if (password_get(pop3_session->user, pop3_session->ac_prefs->recv_server, "pop3", pop3_get_port(pop3_session), &(pop3_session->pass))) { /* NOP */; } else if ((pop3_session->pass = passwd_store_get_account( pop3_session->ac_prefs->account_id, PWS_ACCOUNT_RECV)) == NULL) { gchar *pass; pass = input_dialog_query_password_keep (pop3_session->ac_prefs->recv_server, pop3_session->user, &(pop3_session->ac_prefs->session_passwd)); if (pass) { pop3_session->pass = pass; } } if (inc_dialog->show_dialog) manage_window_focus_out (inc_dialog->dialog->window, NULL, NULL); qlist = next; } #define SET_PIXMAP_AND_TEXT(pix, str) \ { \ progress_dialog_list_set(inc_dialog->dialog, \ inc_dialog->cur_row, \ pix, \ NULL, \ str); \ } for (; inc_dialog->queue_list != NULL && !cancelled; inc_dialog->cur_row++) { session = inc_dialog->queue_list->data; pop3_session = POP3_SESSION(session->session); GSList *filtered, *unfiltered; if (pop3_session->pass == NULL) { SET_PIXMAP_AND_TEXT(okpix, _("Cancelled")); inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); continue; } inc_progress_dialog_clear(inc_dialog); progress_dialog_scroll_to_row(inc_dialog->dialog, inc_dialog->cur_row); SET_PIXMAP_AND_TEXT(currentpix, _("Retrieving")); /* begin POP3 session */ inc_state = inc_pop3_session_do(session); switch (inc_state) { case INC_SUCCESS: if (pop3_session->cur_total_num > 0) msg = g_strdup_printf( ngettext("Done (%d message (%s) received)", "Done (%d messages (%s) received)", pop3_session->cur_total_num), pop3_session->cur_total_num, to_human_readable((goffset)pop3_session->cur_total_recv_bytes)); else msg = g_strdup_printf(_("Done (no new messages)")); SET_PIXMAP_AND_TEXT(okpix, msg); g_free(msg); break; case INC_CONNECT_ERROR: SET_PIXMAP_AND_TEXT(errorpix, _("Connection failed")); break; case INC_AUTH_FAILED: SET_PIXMAP_AND_TEXT(errorpix, _("Auth failed")); if (pop3_session->ac_prefs->session_passwd) { g_free(pop3_session->ac_prefs->session_passwd); pop3_session->ac_prefs->session_passwd = NULL; } break; case INC_LOCKED: SET_PIXMAP_AND_TEXT(errorpix, _("Locked")); break; case INC_ERROR: case INC_NO_SPACE: case INC_IO_ERROR: case INC_SOCKET_ERROR: case INC_EOF: SET_PIXMAP_AND_TEXT(errorpix, _("Error")); break; case INC_TIMEOUT: SET_PIXMAP_AND_TEXT(errorpix, _("Timeout")); break; case INC_CANCEL: SET_PIXMAP_AND_TEXT(okpix, _("Cancelled")); if (!inc_dialog->show_dialog) cancelled = TRUE; break; default: break; } if (pop3_session->error_val == PS_AUTHFAIL) { if(!prefs_common.no_recv_err_panel) { if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) || ((prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL) && focus_window)) manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL); } } /* CLAWS: perform filtering actions on dropped message */ /* CLAWS: get default inbox (perhaps per account) */ if (pop3_session->ac_prefs->inbox) { /* CLAWS: get destination folder / mailbox */ inbox = folder_find_item_from_identifier(pop3_session->ac_prefs->inbox); if (!inbox) inbox = folder_get_default_inbox(); } else inbox = folder_get_default_inbox(); /* get list of messages in processing */ processing = folder_get_default_processing(pop3_session->ac_prefs->account_id); folder_item_scan(processing); msglist = folder_item_get_msg_list(processing); /* process messages */ folder_item_update_freeze(); procmsg_msglist_filter(msglist, pop3_session->ac_prefs, &filtered, &unfiltered, pop3_session->ac_prefs->filter_on_recv); filtering_move_and_copy_msgs(msglist); if (unfiltered != NULL) folder_item_move_msgs(inbox, unfiltered); for(msglist_element = msglist; msglist_element != NULL; msglist_element = msglist_element->next) { procmsg_msginfo_free((MsgInfo**)&(msglist_element->data)); } folder_item_update_thaw(); g_slist_free(msglist); g_slist_free(filtered); g_slist_free(unfiltered); statusbar_pop_all(); new_msgs += pop3_session->cur_total_num; pop3_write_uidl_list(pop3_session); if (inc_state != INC_SUCCESS && inc_state != INC_CANCEL) { error_num++; if (inc_dialog->show_dialog) manage_window_focus_in (inc_dialog->dialog->window, NULL, NULL); inc_put_error(inc_state, pop3_session); if (inc_dialog->show_dialog) manage_window_focus_out (inc_dialog->dialog->window, NULL, NULL); if (inc_state == INC_NO_SPACE || inc_state == INC_IO_ERROR) break; } folder_item_free_cache(processing, TRUE); inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); } #undef SET_PIXMAP_AND_TEXT if (new_msgs > 0) fin_msg = g_strdup_printf(ngettext("Finished (%d new message)", "Finished (%d new messages)", new_msgs), new_msgs); else fin_msg = g_strdup_printf(_("Finished (no new messages)")); progress_dialog_set_label(inc_dialog->dialog, fin_msg); while (inc_dialog->queue_list != NULL) { session = inc_dialog->queue_list->data; inc_session_destroy(session); inc_dialog->queue_list = g_list_remove(inc_dialog->queue_list, session); } if (prefs_common.close_recv_dialog || !inc_dialog->show_dialog) inc_progress_dialog_destroy(inc_dialog); else { gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), fin_msg); gtk_button_set_label(GTK_BUTTON(inc_dialog->dialog->cancel_btn), GTK_STOCK_CLOSE); } g_free(fin_msg); return new_msgs; }
gint send_message_smtp_full(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp, gboolean keep_session) { Session *session; SMTPSession *smtp_session; gushort port = 0; gchar buf[BUFFSIZE]; gint ret = 0; gboolean was_inited = FALSE; MsgInfo *tmp_msginfo = NULL; MsgFlags flags = {0, 0}; long fp_pos = 0; gchar spec_from[BUFFSIZE]; ProxyInfo *proxy_info = NULL; cm_return_val_if_fail(ac_prefs != NULL, -1); cm_return_val_if_fail(ac_prefs->address != NULL, -1); cm_return_val_if_fail(ac_prefs->smtp_server != NULL, -1); cm_return_val_if_fail(to_list != NULL, -1); cm_return_val_if_fail(fp != NULL, -1); /* get the From address used, not necessarily the ac_prefs', * because it's editable. */ fp_pos = ftell(fp); if (fp_pos < 0) { perror("ftell"); return -1; } tmp_msginfo = procheader_parse_stream(fp, flags, TRUE, FALSE); if (fseek(fp, fp_pos, SEEK_SET) < 0) { perror("fseek"); return -1; } if (tmp_msginfo && tmp_msginfo->extradata && tmp_msginfo->extradata->resent_from) { strncpy2(spec_from, tmp_msginfo->extradata->resent_from, BUFFSIZE-1); extract_address(spec_from); } else if (tmp_msginfo && tmp_msginfo->from) { strncpy2(spec_from, tmp_msginfo->from, BUFFSIZE-1); extract_address(spec_from); } else { strncpy2(spec_from, ac_prefs->address, BUFFSIZE-1); } if (tmp_msginfo) { procmsg_msginfo_free(&tmp_msginfo); } if (!ac_prefs->session) { /* we can't reuse a previously initialised session */ session = smtp_session_new(ac_prefs); session->ssl_cert_auto_accept = ac_prefs->ssl_certs_auto_accept; smtp_session = SMTP_SESSION(session); if (ac_prefs->set_domain && ac_prefs->domain && strlen(ac_prefs->domain)) { smtp_session->hostname = g_strdup(ac_prefs->domain); } else { smtp_session->hostname = NULL; } #ifdef USE_GNUTLS port = ac_prefs->set_smtpport ? ac_prefs->smtpport : ac_prefs->ssl_smtp == SSL_TUNNEL ? SSMTP_PORT : SMTP_PORT; session->ssl_type = ac_prefs->ssl_smtp; if (ac_prefs->ssl_smtp != SSL_NONE) session->nonblocking = ac_prefs->use_nonblocking_ssl; if (ac_prefs->set_gnutls_priority && ac_prefs->gnutls_priority && strlen(ac_prefs->gnutls_priority)) session->gnutls_priority = g_strdup(ac_prefs->gnutls_priority); session->use_tls_sni = ac_prefs->use_tls_sni; #else if (ac_prefs->ssl_smtp != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL/TLS, but SSL/TLS is not available " "in this build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, ALERTFOCUS_FIRST, FALSE, NULL, ALERT_WARNING) != G_ALERTALTERNATE) { session_destroy(session); return -1; } } port = ac_prefs->set_smtpport ? ac_prefs->smtpport : SMTP_PORT; #endif if (ac_prefs->use_smtp_auth) { smtp_session->forced_auth_type = ac_prefs->smtp_auth_type; if (ac_prefs->smtp_userid && strlen(ac_prefs->smtp_userid)) { smtp_session->user = g_strdup(ac_prefs->smtp_userid); if (password_get(smtp_session->user, ac_prefs->smtp_server, "smtp", port, &(smtp_session->pass))) { /* NOP */; } else if ((smtp_session->pass = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_SEND)) == NULL) { smtp_session->pass = input_dialog_query_password_keep (ac_prefs->smtp_server, smtp_session->user, &(ac_prefs->session_smtp_passwd)); if (!smtp_session->pass) { session_destroy(session); return -1; } } } else { smtp_session->user = g_strdup(ac_prefs->userid); if (password_get(smtp_session->user, ac_prefs->smtp_server, "smtp", port, &(smtp_session->pass))) { /* NOP */; } else if ((smtp_session->pass = passwd_store_get_account( ac_prefs->account_id, PWS_ACCOUNT_RECV)) == NULL) { smtp_session->pass = input_dialog_query_password_keep (ac_prefs->smtp_server, smtp_session->user, &(ac_prefs->session_smtp_passwd)); if (!smtp_session->pass) { session_destroy(session); return -1; } } } } else { smtp_session->user = NULL; smtp_session->pass = NULL; } send_dialog = send_progress_dialog_create(); send_dialog->session = session; smtp_session->dialog = send_dialog; progress_dialog_list_set(send_dialog->dialog, 0, NULL, ac_prefs->smtp_server, _("Connecting")); if (ac_prefs->pop_before_smtp && (ac_prefs->protocol == A_POP3) && (time(NULL) - ac_prefs->last_pop_login_time) > (60 * ac_prefs->pop_before_smtp_timeout)) { g_snprintf(buf, sizeof(buf), _("Doing POP before SMTP...")); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(send_dialog->dialog, buf); progress_dialog_list_set_status(send_dialog->dialog, 0, _("POP before SMTP")); GTK_EVENTS_FLUSH(); inc_pop_before_smtp(ac_prefs); } g_snprintf(buf, sizeof(buf), _("Account '%s': Connecting to SMTP server: %s:%d..."), ac_prefs->account_name, ac_prefs->smtp_server, port); progress_dialog_set_label(send_dialog->dialog, buf); log_message(LOG_PROTOCOL, "%s\n", buf); session_set_recv_message_notify(session, send_recv_message, send_dialog); session_set_send_data_progressive_notify (session, send_send_data_progressive, send_dialog); session_set_send_data_notify(session, send_send_data_finished, send_dialog); } else { /* everything is ready to start at MAIL FROM:, just * reinit useful variables. */ session = SESSION(ac_prefs->session); ac_prefs->session = NULL; smtp_session = SMTP_SESSION(session); smtp_session->state = SMTP_HELO; send_dialog = (SendProgressDialog *)smtp_session->dialog; was_inited = TRUE; } /* This has to be initialised for every mail sent */ smtp_session->from = g_strdup(spec_from); smtp_session->to_list = to_list; smtp_session->cur_to = to_list; smtp_session->send_data = (guchar *)get_outgoing_rfc2822_str(fp); smtp_session->send_data_len = strlen((gchar *)smtp_session->send_data); if (ac_prefs->use_proxy && ac_prefs->use_proxy_for_send) { if (ac_prefs->use_default_proxy) { proxy_info = (ProxyInfo *)&(prefs_common.proxy_info); if (proxy_info->use_proxy_auth) proxy_info->proxy_pass = passwd_store_get(PWS_CORE, PWS_CORE_PROXY, PWS_CORE_PROXY_PASS); } else { proxy_info = (ProxyInfo *)&(ac_prefs->proxy_info); if (proxy_info->use_proxy_auth) proxy_info->proxy_pass = passwd_store_get_account(ac_prefs->account_id, PWS_ACCOUNT_PROXY_PASS); } } SESSION(smtp_session)->proxy_info = proxy_info; session_set_timeout(session, prefs_common.io_timeout_secs * 1000); /* connect if necessary */ if (!was_inited && session_connect(session, ac_prefs->smtp_server, port) < 0) { session_destroy(session); send_progress_dialog_destroy(send_dialog); ac_prefs->session = NULL; return -1; } debug_print("send_message_smtp(): begin event loop\n"); if (was_inited) { /* as the server is quiet, start sending ourselves */ smtp_from(smtp_session); } while (session_is_running(session) && send_dialog->cancelled == FALSE && SMTP_SESSION(session)->state != SMTP_MAIL_SENT_OK) gtk_main_iteration(); if (SMTP_SESSION(session)->error_val == SM_AUTHFAIL) { if (ac_prefs->session_smtp_passwd) { g_free(ac_prefs->session_smtp_passwd); ac_prefs->session_smtp_passwd = NULL; } ret = -1; } else if (SMTP_SESSION(session)->state == SMTP_MAIL_SENT_OK) { log_message(LOG_PROTOCOL, "%s\n", _("Mail sent successfully.")); ret = 0; } else if (session->state == SESSION_EOF && SMTP_SESSION(session)->state == SMTP_QUIT) { /* consider EOF right after QUIT successful */ log_warning(LOG_PROTOCOL, "%s\n", _("Connection closed by the remote host.")); ret = 0; } else if (session->state == SESSION_ERROR || session->state == SESSION_EOF || session->state == SESSION_TIMEOUT || SMTP_SESSION(session)->state == SMTP_ERROR || SMTP_SESSION(session)->error_val != SM_OK) ret = -1; else if (send_dialog->cancelled == TRUE) ret = -1; if (ret == -1) { manage_window_focus_in(send_dialog->dialog->window, NULL, NULL); send_put_error(session); manage_window_focus_out(send_dialog->dialog->window, NULL, NULL); } /* if we should close the connection, let's do it. * Close it in case of error, too, as it helps reinitializing things * easier. */ if (!keep_session || ret != 0) { if (session_is_connected(session)) smtp_quit(smtp_session); while (session_is_connected(session) && !send_dialog->cancelled) gtk_main_iteration(); session_destroy(session); ac_prefs->session = NULL; send_progress_dialog_destroy(send_dialog); } else { g_free(smtp_session->from); g_free(smtp_session->send_data); g_free(smtp_session->error_msg); } if (keep_session && ret == 0 && ac_prefs->session == NULL) ac_prefs->session = SMTP_SESSION(session); statusbar_pop_all(); statusbar_verbosity_set(FALSE); return ret; }
static Session *news_session_new_for_folder(Folder *folder) { Session *session; PrefsAccount *ac; const gchar *userid = NULL; gchar *passwd = NULL; gushort port; int r; cm_return_val_if_fail(folder != NULL, NULL); cm_return_val_if_fail(folder->account != NULL, NULL); ac = folder->account; #ifdef USE_GNUTLS port = ac->set_nntpport ? ac->nntpport : ac->ssl_nntp ? NNTPS_PORT : NNTP_PORT; session = news_session_new(folder, ac->nntp_server, port, userid, passwd, ac->ssl_nntp); #else if (ac->ssl_nntp != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL, but SSL is not available in this " "build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) return NULL; } port = ac->set_nntpport ? ac->nntpport : NNTP_PORT; session = news_session_new(folder, ac->nntp_server, port, userid, passwd); #endif if (ac->use_nntp_auth && ac->userid && ac->userid[0]) { userid = ac->userid; if (password_get(userid, ac->nntp_server, "nntp", port, &passwd)) { /* NOP */; } else if ((passwd = passwd_store_get_account(ac->account_id, PWS_ACCOUNT_RECV)) == NULL) { passwd = input_dialog_query_password_keep(ac->nntp_server, userid, &(ac->session_passwd)); } } if (session != NULL) r = nntp_threaded_mode_reader(folder); else r = NEWSNNTP_ERROR_CONNECTION_REFUSED; if (r != NEWSNNTP_NO_ERROR) { if (r == NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME) { /* FIX ME when libetpan implements 480 to indicate authorization is required to use this capability. Libetpan treats a 480 as a 381 which is clearly wrong. RFC 4643 section 2. Response code 480 Generic response Meaning: command unavailable until the client has authenticated itself. */ /* if the server does not advertise the capability MODE-READER, we normally should not send MODE READER. However this can't hurt: a transit-only server returns 502 and closes the cnx. Ref.: http://tools.ietf.org/html/rfc3977#section-5.3 */ log_error(LOG_PROTOCOL, _("Libetpan does not support return code 480 " "so for now we choose to continue\n")); } else if (r == NEWSNNTP_ERROR_UNEXPECTED_RESPONSE) { /* if the server does not advertise the capability MODE-READER, we normally should not send MODE READER. However this can't hurt: a transit-only server returns 502 and closes the cnx. Ref.: http://tools.ietf.org/html/rfc3977#section-5.3 */ log_error(LOG_PROTOCOL, _("Mode reader failed, continuing nevertheless\n")); } else { /* An error state bail out */ log_error(LOG_PROTOCOL, _("Error creating session with %s:%d\n"), ac->nntp_server, port); if (session != NULL) session_destroy(SESSION(session)); g_free(passwd); if (ac->session_passwd) { g_free(ac->session_passwd); ac->session_passwd = NULL; } return NULL; } } if ((session != NULL) && ac->use_nntp_auth) { /* FIXME: && ac->use_nntp_auth_onconnect */ if (nntp_threaded_login(folder, userid, passwd) != NEWSNNTP_NO_ERROR) { log_error(LOG_PROTOCOL, _("Error authenticating to %s:%d...\n"), ac->nntp_server, port); session_destroy(SESSION(session)); g_free(passwd); if (ac->session_passwd) { g_free(ac->session_passwd); ac->session_passwd = NULL; } return NULL; } } g_free(passwd); return session; }