static void pop3_gen_send(Pop3Session *session, const gchar *format, ...) { gchar buf[POPBUFSIZE + 1]; va_list args; va_start(args, format); g_vsnprintf(buf, sizeof(buf) - 2, format, args); va_end(args); if (!g_ascii_strncasecmp(buf, "PASS ", 5)) log_print(LOG_PROTOCOL, "POP3> PASS ********\n"); else log_print(LOG_PROTOCOL, "POP3> %s\n", buf); session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf); }
static gint smtp_ehlo(SMTPSession *session) { gchar buf[MESSAGEBUFSIZE]; session->state = SMTP_EHLO; session->avail_auth_type = 0; g_snprintf(buf, sizeof(buf), "EHLO %s", session->hostname ? session->hostname : get_domain_name()); if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf) < 0) return SM_ERROR; log_print(LOG_PROTOCOL, "ESMTP> %s\n", buf); return SM_OK; }
static gint smtp_auth_login_user_recv(SMTPSession *session, const gchar *msg) { gchar buf[MSGBUFSIZE]; session->state = SMTP_AUTH_LOGIN_PASS; if (!strncmp(msg, "334 ", 4)) base64_encode(buf, session->pass, strlen(session->pass)); else /* Server rejects AUTH */ g_snprintf(buf, sizeof(buf), "*"); session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf); log_print("ESMTP> [PASSWORD]\n"); return SM_OK; }
int main(int argc, char** argv){ parse_command_arguments(argc,argv); // for now we take the first arg and use it as the filename for xml std::cout << "resoundnv server v0.0.1\n"; std::cout << "Loading config from " << g_options.inputXML_ << std::endl; // loading and parsing the xml // try // { xmlpp::DomParser parser; parser.set_validate(false); parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically. parser.parse_file(g_options.inputXML_); if(parser){ const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser. const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(pNode); if(nodeElement) { std::string name = nodeElement->get_name(); if(name=="resoundnv"){ std::cout << "Resoundnv XML node found, building session.\n"; g_session = new ResoundSession(g_options); APP().set_session(g_session); SESSION().load_from_xml(nodeElement); } } } // } // catch(const std::exception& ex){ // std::cout << "XML Initialisation file parsing exception what()=" << ex.what() << std::endl; // std::cout << "Server cannot continue"<< std::endl; // std::exit(1); // } signal(SIGINT, handle_sigint); g_continue = true; while(g_continue){ // TODO this should really listen for incoming signals, see unix programming book. usleep(100000); // around 10 fps // use this thread to send some feedback //session->update_clients(); if(g_session) g_session->send_osc_feedback(); } delete g_session; // should invoke destructor g_session=0; return 0; }
Session *smtp_session_new(void) { SMTPSession *session; session = g_new0(SMTPSession, 1); session_init(SESSION(session)); SESSION(session)->type = SESSION_SMTP; SESSION(session)->recv_msg = smtp_session_recv_msg; SESSION(session)->recv_data_finished = NULL; SESSION(session)->send_data_finished = smtp_session_send_data_finished; SESSION(session)->destroy = smtp_session_destroy; session->state = SMTP_READY; #if USE_OPENSSL session->tls_init_done = FALSE; #endif session->hostname = NULL; session->user = NULL; session->pass = NULL; session->from = NULL; session->to_list = NULL; session->cur_to = NULL; session->send_data = NULL; session->send_data_len = 0; session->max_message_size = -1; session->avail_auth_type = 0; session->forced_auth_type = 0; session->auth_type = 0; session->esmtp_flags = 0; session->error_val = SM_OK; session->error_msg = NULL; return SESSION(session); }
Session *pop3_session_new(PrefsAccount *account) { Pop3Session *session; cm_return_val_if_fail(account != NULL, NULL); account->receive_in_progress = TRUE; session = g_new0(Pop3Session, 1); session_init(SESSION(session), account, FALSE); SESSION(session)->type = SESSION_POP3; SESSION(session)->recv_msg = pop3_session_recv_msg; SESSION(session)->recv_data_finished = pop3_session_recv_data_finished; SESSION(session)->send_data_finished = NULL; SESSION(session)->ssl_cert_auto_accept = account->ssl_certs_auto_accept; SESSION(session)->destroy = pop3_session_destroy; #ifdef USE_GNUTLS if (account->set_gnutls_priority && account->gnutls_priority && strlen(account->gnutls_priority) != 0) SESSION(session)->gnutls_priority = g_strdup(account->gnutls_priority); #endif session->state = POP3_READY; session->ac_prefs = account; session->pop_before_smtp = FALSE; pop3_get_uidl_table(account, session); session->current_time = time(NULL); session->error_val = PS_SUCCESS; session->error_msg = NULL; return SESSION(session); }
static Session *news_session_new(Folder *folder, const gchar *server, gushort port, const gchar *userid, const gchar *passwd) #endif { NewsSession *session; int r = 0; cm_return_val_if_fail(server != NULL, NULL); log_message(LOG_PROTOCOL, _("Account '%s': Connecting to NNTP server: %s:%d...\n"), folder->account->account_name, server, port); session = g_new0(NewsSession, 1); session_init(SESSION(session), folder->account, FALSE); SESSION(session)->type = SESSION_NEWS; SESSION(session)->server = g_strdup(server); SESSION(session)->port = port; SESSION(session)->sock = NULL; SESSION(session)->destroy = news_session_destroy; nntp_init(folder); #ifdef USE_GNUTLS if (ssl_type != SSL_NONE) r = nntp_threaded_connect_ssl(folder, server, port); else #endif r = nntp_threaded_connect(folder, server, port); if (r != NEWSNNTP_NO_ERROR) { log_error(LOG_PROTOCOL, _("Error logging in to %s:%d...\n"), server, port); session_destroy(SESSION(session)); return NULL; } session->folder = folder; return SESSION(session); }
static gint smtp_rcpt(SMTPSession *session) { gchar buf[MSGBUFSIZE]; gchar *to; g_return_val_if_fail(session->cur_to != NULL, SM_ERROR); session->state = SMTP_RCPT; to = (gchar *)session->cur_to->data; if (strchr(to, '<')) g_snprintf(buf, sizeof(buf), "RCPT TO:%s", to); else g_snprintf(buf, sizeof(buf), "RCPT TO:<%s>", to); session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf); log_print("SMTP> %s\n", buf); session->cur_to = session->cur_to->next; return SM_OK; }
static gint smtp_auth_login_user_recv(SMTPSession *session, const gchar *msg) { gchar *tmp; session->state = SMTP_AUTH_LOGIN_PASS; if (!strncmp(msg, "334 ", 4)) { tmp = g_base64_encode(session->pass, strlen(session->pass)); } else { /* Server rejects AUTH */ tmp = g_strdup("*"); } if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, tmp) < 0) { g_free(tmp); return SM_ERROR; } g_free(tmp); log_print(LOG_PROTOCOL, "ESMTP> [PASSWORD]\n"); return SM_OK; }
static gint session_connect_cb(SockInfo *sock, gpointer data) { Session *session = SESSION(data); session->conn_id = 0; if (!sock) { g_warning("can't connect to server."); session->state = SESSION_ERROR; return -1; } session->sock = sock; #if USE_OPENSSL if (session->ssl_type == SSL_TUNNEL) { sock_set_nonblocking_mode(sock, FALSE); if (!ssl_init_socket(sock)) { g_warning("can't initialize SSL."); session->state = SESSION_ERROR; return -1; } } #endif sock_set_nonblocking_mode(sock, session->nonblocking); debug_print("session (%p): connected\n", session); session->state = SESSION_RECV; session->io_tag = sock_add_watch(session->sock, G_IO_IN, session_read_msg_cb, session); return 0; }
static gint smtp_auth_recv(SMTPSession *session, const gchar *msg) { gchar buf[MSGBUFSIZE]; switch (session->auth_type) { case SMTPAUTH_LOGIN: session->state = SMTP_AUTH_LOGIN_USER; if (!strncmp(msg, "334 ", 4)) { base64_encode(buf, session->user, strlen(session->user)); session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf); log_print("ESMTP> [USERID]\n"); } else { /* Server rejects AUTH */ session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*"); log_print("ESMTP> *\n"); } break; case SMTPAUTH_CRAM_MD5: session->state = SMTP_AUTH_CRAM_MD5; if (!strncmp(msg, "334 ", 4)) { gchar *response; gchar *response64; gchar *challenge; gint challengelen; guchar hexdigest[33]; challenge = g_malloc(strlen(msg + 4) + 1); challengelen = base64_decode(challenge, msg + 4, -1); challenge[challengelen] = '\0'; log_print("ESMTP< [Decoded: %s]\n", challenge); g_snprintf(buf, sizeof(buf), "%s", session->pass); md5_hex_hmac(hexdigest, challenge, challengelen, buf, strlen(session->pass)); g_free(challenge); response = g_strdup_printf ("%s %s", session->user, hexdigest); log_print("ESMTP> [Encoded: %s]\n", response); response64 = g_malloc((strlen(response) + 3) * 2 + 1); base64_encode(response64, response, strlen(response)); g_free(response); session_send_msg(SESSION(session), SESSION_MSG_NORMAL, response64); log_print("ESMTP> %s\n", response64); g_free(response64); } else { /* Server rejects AUTH */ session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*"); log_print("ESMTP> *\n"); } break; case SMTPAUTH_DIGEST_MD5: default: /* stop smtp_auth when no correct authtype */ session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*"); log_print("ESMTP> *\n"); break; } return SM_OK; }
static gboolean session_read_data_cb(SockInfo *source, GIOCondition condition, gpointer data) { Session *session = SESSION(data); GByteArray *data_buf; gint terminator_len; gboolean complete = FALSE; guint data_len; gint ret; g_return_val_if_fail(condition == G_IO_IN, FALSE); session_set_timeout(session, session->timeout_interval); if (session->read_buf_len == 0) { gint read_len; read_len = sock_read(session->sock, session->read_buf, SESSION_BUFFSIZE); if (read_len == 0) { g_warning("sock_read: received EOF\n"); session->state = SESSION_EOF; return FALSE; } if (read_len < 0) { switch (errno) { case EAGAIN: return TRUE; default: g_warning("sock_read: %s\n", g_strerror(errno)); session->state = SESSION_ERROR; return FALSE; } } session->read_buf_len = read_len; } data_buf = session->read_data_buf; terminator_len = strlen(session->read_data_terminator); if (session->read_buf_len == 0) return TRUE; g_byte_array_append(data_buf, session->read_buf_p, session->read_buf_len); session->read_buf_len = 0; session->read_buf_p = session->read_buf; /* check if data is terminated */ if (data_buf->len >= terminator_len) { if (memcmp(data_buf->data, session->read_data_terminator, terminator_len) == 0) complete = TRUE; else if (data_buf->len >= terminator_len + 2 && memcmp(data_buf->data + data_buf->len - (terminator_len + 2), "\r\n", 2) == 0 && memcmp(data_buf->data + data_buf->len - terminator_len, session->read_data_terminator, terminator_len) == 0) complete = TRUE; } /* incomplete read */ if (!complete) { struct timeval tv_cur; gettimeofday(&tv_cur, NULL); if (tv_cur.tv_sec - session->tv_prev.tv_sec > 0 || tv_cur.tv_usec - session->tv_prev.tv_usec > UI_REFRESH_INTERVAL) { session->recv_data_progressive_notify (session, data_buf->len, 0, session->recv_data_progressive_notify_data); gettimeofday(&session->tv_prev, NULL); } return TRUE; } /* complete */ if (session->io_tag > 0) { g_source_remove(session->io_tag); session->io_tag = 0; } data_len = data_buf->len - terminator_len; /* callback */ ret = session->recv_data_finished(session, (gchar *)data_buf->data, data_len); g_byte_array_set_size(data_buf, 0); session->recv_data_notify(session, data_len, session->recv_data_notify_data); if (ret < 0) session->state = SESSION_ERROR; return FALSE; }
static gboolean session_read_msg_cb(SockInfo *source, GIOCondition condition, gpointer data) { Session *session = SESSION(data); gchar buf[SESSION_BUFFSIZE]; gint line_len; gchar *newline; gchar *msg; gint ret; g_return_val_if_fail(condition == G_IO_IN, FALSE); session_set_timeout(session, session->timeout_interval); if (session->read_buf_len == 0) { gint read_len; read_len = sock_read(session->sock, session->read_buf, SESSION_BUFFSIZE - 1); if (read_len == 0) { g_warning("sock_read: received EOF\n"); session->state = SESSION_EOF; return FALSE; } if (read_len < 0) { switch (errno) { case EAGAIN: return TRUE; default: g_warning("sock_read: %s\n", g_strerror(errno)); session->state = SESSION_ERROR; return FALSE; } } session->read_buf_len = read_len; } if ((newline = memchr(session->read_buf_p, '\n', session->read_buf_len)) != NULL) line_len = newline - session->read_buf_p + 1; else line_len = session->read_buf_len; if (line_len == 0) return TRUE; memcpy(buf, session->read_buf_p, line_len); buf[line_len] = '\0'; g_string_append(session->read_msg_buf, buf); session->read_buf_len -= line_len; if (session->read_buf_len == 0) session->read_buf_p = session->read_buf; else session->read_buf_p += line_len; /* incomplete read */ if (buf[line_len - 1] != '\n') return TRUE; /* complete */ if (session->io_tag > 0) { g_source_remove(session->io_tag); session->io_tag = 0; } /* callback */ msg = g_strdup(session->read_msg_buf->str); strretchomp(msg); g_string_truncate(session->read_msg_buf, 0); ret = session->recv_msg(session, msg); session->recv_msg_notify(session, msg, session->recv_msg_notify_data); g_free(msg); if (ret < 0) session->state = SESSION_ERROR; return FALSE; }
static gint sieve_auth_recv(SieveSession *session, const gchar *msg) { gchar buf[MESSAGEBUFSIZE], *tmp; switch (session->auth_type) { case SIEVEAUTH_LOGIN: session->state = SIEVE_AUTH_LOGIN_USER; if (strstr(msg, "VXNlcm5hbWU6")) { tmp = g_base64_encode(session->user, strlen(session->user)); g_snprintf(buf, sizeof(buf), "\"%s\"", tmp); if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf) < 0) { g_free(tmp); return SE_ERROR; } g_free(tmp); log_print(LOG_PROTOCOL, "Sieve> [USERID]\n"); } else { /* Server rejects AUTH */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "\"*\"") < 0) return SE_ERROR; log_print(LOG_PROTOCOL, "Sieve> *\n"); } break; case SIEVEAUTH_CRAM_MD5: session->state = SIEVE_AUTH_CRAM_MD5; if (msg[0] == '"') { gchar *response; gchar *response64; gchar *challenge, *tmp; gsize challengelen; guchar hexdigest[33]; tmp = g_base64_decode(msg + 1, &challengelen); challenge = g_strndup(tmp, challengelen); g_free(tmp); log_print(LOG_PROTOCOL, "Sieve< [Decoded: %s]\n", challenge); g_snprintf(buf, sizeof(buf), "%s", session->pass); md5_hex_hmac(hexdigest, challenge, challengelen, buf, strlen(session->pass)); g_free(challenge); response = g_strdup_printf ("%s %s", session->user, hexdigest); log_print(LOG_PROTOCOL, "Sieve> [Encoded: %s]\n", response); response64 = g_base64_encode(response, strlen(response)); g_free(response); response = g_strdup_printf("\"%s\"", response64); g_free(response64); if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, response) < 0) { g_free(response); return SE_ERROR; } log_print(LOG_PROTOCOL, "Sieve> %s\n", response); g_free(response); } else { /* Server rejects AUTH */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "\"*\"") < 0) return SE_ERROR; log_print(LOG_PROTOCOL, "Sieve> *\n"); } break; default: /* stop sieve_auth when no correct authtype */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*") < 0) return SE_ERROR; log_print(LOG_PROTOCOL, "Sieve> *\n"); break; } return SE_OK; }
static IncState inc_pop3_session_do(IncSession *session) { Pop3Session *pop3_session = POP3_SESSION(session->session); IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data; gchar *server; gchar *account_name; gushort port; gchar *buf; debug_print("getting new messages of account %s...\n", pop3_session->ac_prefs->account_name); pop3_session->ac_prefs->last_pop_login_time = time(NULL); buf = g_strdup_printf(_("%s: Retrieving new messages"), pop3_session->ac_prefs->recv_server); gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf); g_free(buf); server = pop3_session->ac_prefs->recv_server; account_name = pop3_session->ac_prefs->account_name; #ifdef USE_GNUTLS port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110; SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop; if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) SESSION(pop3_session)->nonblocking = pop3_session->ac_prefs->use_nonblocking_ssl; #else if (pop3_session->ac_prefs->ssl_pop != 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 INC_CANCEL; } port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : 110; #endif buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."), account_name, server, port); statuswindow_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(inc_dialog->dialog, buf); GTK_EVENTS_FLUSH(); g_free(buf); session_set_timeout(SESSION(pop3_session), prefs_common.io_timeout_secs * 1000); if (session_connect(SESSION(pop3_session), server, port) < 0) { 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); } alertpanel_error(_("Can't connect to POP3 server: %s:%d"), server, port); manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL); } else { log_error(LOG_PROTOCOL, _("Can't connect to POP3 server: %s:%d\n"), server, port); } session->inc_state = INC_CONNECT_ERROR; statuswindow_pop_all(); return INC_CONNECT_ERROR; } while (session_is_running(SESSION(pop3_session)) && session->inc_state != INC_CANCEL) gtk_main_iteration(); if (session->inc_state == INC_SUCCESS) { switch (pop3_session->error_val) { case PS_SUCCESS: switch (SESSION(pop3_session)->state) { case SESSION_ERROR: if (pop3_session->state == POP3_READY) session->inc_state = INC_CONNECT_ERROR; else session->inc_state = INC_ERROR; break; case SESSION_EOF: session->inc_state = INC_EOF; break; case SESSION_TIMEOUT: session->inc_state = INC_TIMEOUT; break; default: session->inc_state = INC_SUCCESS; break; } break; case PS_AUTHFAIL: session->inc_state = INC_AUTH_FAILED; break; case PS_IOERR: session->inc_state = INC_IO_ERROR; break; case PS_SOCKET: session->inc_state = INC_SOCKET_ERROR; break; case PS_LOCKBUSY: session->inc_state = INC_LOCKED; break; default: session->inc_state = INC_ERROR; break; } } session_disconnect(SESSION(pop3_session)); statusbar_pop_all(); return session->inc_state; }
static gint smtp_auth_recv(SMTPSession *session, const gchar *msg) { gchar buf[MESSAGEBUFSIZE], *tmp; switch (session->auth_type) { case SMTPAUTH_LOGIN: session->state = SMTP_AUTH_LOGIN_USER; if (!strncmp(msg, "334 ", 4)) { tmp = g_base64_encode(session->user, strlen(session->user)); if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, tmp) < 0) { g_free(tmp); return SM_ERROR; } g_free(tmp); log_print(LOG_PROTOCOL, "ESMTP> [USERID]\n"); } else { /* Server rejects AUTH */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*") < 0) return SM_ERROR; log_print(LOG_PROTOCOL, "ESMTP> *\n"); } break; case SMTPAUTH_CRAM_MD5: session->state = SMTP_AUTH_CRAM_MD5; if (!strncmp(msg, "334 ", 4)) { gchar *response; gchar *response64; gchar *challenge; gsize challengelen; guchar hexdigest[33]; challenge = g_base64_decode_zero(msg + 4, &challengelen); log_print(LOG_PROTOCOL, "ESMTP< [Decoded: %s]\n", challenge); g_snprintf(buf, sizeof(buf), "%s", session->pass); md5_hex_hmac(hexdigest, challenge, challengelen, buf, strlen(session->pass)); g_free(challenge); response = g_strdup_printf ("%s %s", session->user, hexdigest); log_print(LOG_PROTOCOL, "ESMTP> [Encoded: %s]\n", response); response64 = g_base64_encode(response, strlen(response)); g_free(response); if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, response64) < 0) { g_free(response64); return SM_ERROR; } log_print(LOG_PROTOCOL, "ESMTP> %s\n", response64); g_free(response64); } else { /* Server rejects AUTH */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*") < 0) return SM_ERROR; log_print(LOG_PROTOCOL, "ESMTP> *\n"); } break; case SMTPAUTH_DIGEST_MD5: default: /* stop smtp_auth when no correct authtype */ if (session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*") < 0) return SM_ERROR; log_print(LOG_PROTOCOL, "ESMTP> *\n"); break; } return SM_OK; }
static void news_get_extra_fields(NewsSession *session, FolderItem *item, GSList *msglist) { MsgInfo *msginfo = NULL; gint ok; GSList *cur; clist *hdrlist = NULL; clistiter *hdr; gint first = -1, last = -1; GHashTable *hash_table; cm_return_if_fail(session != NULL); cm_return_if_fail(item != NULL); cm_return_if_fail(item->folder != NULL); cm_return_if_fail(FOLDER_CLASS(item->folder) == &news_class); news_folder_lock(NEWS_FOLDER(item->folder)); hash_table = g_hash_table_new(g_direct_hash, g_direct_equal); for (cur = msglist; cur; cur = cur->next) { msginfo = (MsgInfo *)cur->data; if (first == -1 || msginfo->msgnum < first) first = msginfo->msgnum; if (last == -1 || msginfo->msgnum > last) last = msginfo->msgnum; g_hash_table_insert(hash_table, GINT_TO_POINTER(msginfo->msgnum), msginfo); } /* Newsgroups */ ok = nntp_threaded_xhdr(item->folder, "newsgroups", first, last, &hdrlist); if (ok != NEWSNNTP_NO_ERROR) { log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n")); if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); return; } for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) { struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr); msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article)); if (msginfo) { if (msginfo->newsgroups) g_free(msginfo->newsgroups); msginfo->newsgroups = g_strdup(hdrval->hdr_value); } } newsnntp_xhdr_free(hdrlist); /* To */ ok = nntp_threaded_xhdr(item->folder, "to", first, last, &hdrlist); if (ok != NEWSNNTP_NO_ERROR) { log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n")); if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); return; } for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) { struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr); msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article)); if (msginfo) { if (msginfo->to) g_free(msginfo->to); msginfo->to = g_strdup(hdrval->hdr_value); } } newsnntp_xhdr_free(hdrlist); /* Cc */ ok = nntp_threaded_xhdr(item->folder, "cc", first, last, &hdrlist); if (ok != NEWSNNTP_NO_ERROR) { log_warning(LOG_PROTOCOL, _("couldn't get xhdr\n")); if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); return; } for (hdr = clist_begin(hdrlist); hdr; hdr = clist_next(hdr)) { struct newsnntp_xhdr_resp_item *hdrval = clist_content(hdr); msginfo = g_hash_table_lookup(hash_table, GINT_TO_POINTER(hdrval->hdr_article)); if (msginfo) { if (msginfo->cc) g_free(msginfo->cc); msginfo->cc = g_strdup(hdrval->hdr_value); } } newsnntp_xhdr_free(hdrlist); g_hash_table_destroy(hash_table); news_folder_unlock(NEWS_FOLDER(item->folder)); }
GSList *news_get_group_list(Folder *folder) { gchar *path, *filename; FILE *fp; GSList *list = NULL; GSList *last = NULL; gchar buf[BUFFSIZE]; cm_return_val_if_fail(folder != NULL, NULL); cm_return_val_if_fail(FOLDER_CLASS(folder) == &news_class, NULL); path = folder_item_get_path(FOLDER_ITEM(folder->node->data)); if (!is_dir_exist(path)) make_dir_hier(path); filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL); g_free(path); if ((fp = g_fopen(filename, "rb")) == NULL) { NewsSession *session; gint ok; clist *grouplist = NULL; clistiter *cur; fp = g_fopen(filename, "wb"); if (!fp) { g_free(filename); return NULL; } session = news_session_get(folder); if (!session) { fclose(fp); g_free(filename); return NULL; } ok = nntp_threaded_list(folder, &grouplist); if (ok != NEWSNNTP_NO_ERROR) { if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; } fclose(fp); g_free(filename); return NULL; } if (grouplist) { for (cur = clist_begin(grouplist); cur; cur = clist_next(cur)) { struct newsnntp_group_info *info = (struct newsnntp_group_info *) clist_content(cur); if (fprintf(fp, "%s %d %d %c\n", info->grp_name, info->grp_last, info->grp_first, info->grp_type) < 0) { log_error(LOG_PROTOCOL, ("Can't write newsgroup list\n")); session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; fclose(fp); g_free(filename); newsnntp_list_free(grouplist); return NULL; } } newsnntp_list_free(grouplist); } if (fclose(fp) == EOF) { log_error(LOG_PROTOCOL, ("Can't write newsgroup list\n")); session_destroy(SESSION(session)); REMOTE_FOLDER(folder)->session = NULL; g_free(filename); return NULL; } if ((fp = g_fopen(filename, "rb")) == NULL) { FILE_OP_ERROR(filename, "fopen"); g_free(filename); return NULL; } } while (fgets(buf, sizeof(buf), fp) != NULL) { gchar *p = buf; gchar *name; gint last_num; gint first_num; gchar type; NewsGroupInfo *ginfo; p = strchr(p, ' '); if (!p) continue; *p = '\0'; p++; name = buf; if (sscanf(p, "%d %d %c", &last_num, &first_num, &type) < 3) continue; ginfo = news_group_info_new(name, first_num, last_num, type); if (!last) last = list = g_slist_append(NULL, ginfo); else { last = g_slist_append(last, ginfo); last = last->next; } } fclose(fp); g_free(filename); list = g_slist_sort(list, (GCompareFunc)news_group_info_compare); return list; }
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; }
static GSList *news_get_msginfos_for_range(NewsSession *session, FolderItem *item, guint begin, guint end) { GSList *newlist = NULL; GSList *llast = NULL; MsgInfo *msginfo; gint ok; clist *msglist = NULL; clistiter *cur; cm_return_val_if_fail(session != NULL, NULL); cm_return_val_if_fail(item != NULL, NULL); log_message(LOG_PROTOCOL, _("getting xover %d - %d in %s...\n"), begin, end, item->path); news_folder_lock(NEWS_FOLDER(item->folder)); ok = news_select_group(item->folder, item->path, NULL, NULL, NULL); if (ok != NEWSNNTP_NO_ERROR) { log_warning(LOG_PROTOCOL, _("couldn't set group: %s\n"), item->path); news_folder_unlock(NEWS_FOLDER(item->folder)); return NULL; } ok = nntp_threaded_xover(item->folder, begin, end, NULL, &msglist); if (ok != NEWSNNTP_NO_ERROR) { log_warning(LOG_PROTOCOL, _("couldn't get xover\n")); if (ok == NEWSNNTP_ERROR_STREAM) { session_destroy(SESSION(session)); REMOTE_FOLDER(item->folder)->session = NULL; } news_folder_unlock(NEWS_FOLDER(item->folder)); return NULL; } if (msglist) { for (cur = clist_begin(msglist); cur; cur = clist_next(cur)) { struct newsnntp_xover_resp_item *ritem = (struct newsnntp_xover_resp_item *)clist_content(cur); msginfo = news_parse_xover(ritem); if (!msginfo) { log_warning(LOG_PROTOCOL, _("invalid xover line\n")); continue; } msginfo->folder = item; news_set_msg_flags(item, msginfo); msginfo->flags.tmp_flags |= MSG_NEWS; if (!newlist) llast = newlist = g_slist_append(newlist, msginfo); else { llast = g_slist_append(llast, msginfo); llast = llast->next; } } newsnntp_xover_resp_list_free(msglist); } news_folder_unlock(NEWS_FOLDER(item->folder)); session_set_access_time(SESSION(session)); news_get_extra_fields(session, item, newlist); return newlist; }
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; }
/** * The ev client io callback */ void client_io_avail(struct ev_loop* loop, struct ev_io* io_read, int revents) { client_t* client = container_of(io_read, client_t, io_read); // Check for errors if (EV_ERROR & revents) { ERROR("invalid event"); return; } server_t* server = client->server; bool report_read = false; if (client->client_drop) { server_client_cleanup(server, client); return; } if (revents & EV_READ) { int read_avail = recv(client->fd, server->buffer, server->buf_size, 0); // Check for read error if (read_avail < 0) { switch (errno) { case ECONNRESET: case ETIMEDOUT: read_avail = 0; // drop the client later on break; default: ERROR("unable to handle error: %s", strerror(errno)); break; } return; } // Check for client drop if (read_avail == 0) { server_client_drop(server, client); SESSION("client dropped"); return; } int buffered = buffer_write(&client->read_buffer, server->buffer, read_avail); if (buffered != read_avail) { WARN("buffer overflow. dropping %i bytes", read_avail-buffered); } if (client->handshake_stage == HANDSHAKE_ACCEPTED) { report_read = true; } } if (revents & EV_WRITE) { // flush write buffer if necessary if (client->handshake_stage == HANDSHAKE_ACCEPTED) { server->write_cb(client, server); } size_t write_avail = buffer_read(&client->write_buffer, server->buffer, server->buf_size); size_t write_caret = 0; while (write_avail > write_caret) { ssize_t sent = send(client->fd, server->buffer+write_caret, write_avail, 0); // Check for write error if (sent < 0) { switch (errno) { case ECONNRESET: case ETIMEDOUT: sent = 0; // drop the client later on break; default: ERROR("unable to handle error: %s", strerror(errno)); break; } return; } // Check for client drop if (sent == 0) { server_client_drop(server, client); SESSION("client dropped"); return; } write_caret += sent; } } if (client->handshake_stage == HANDSHAKE_PENDING) { client->handshake_stage = server->handshake_cb(client, server); switch (client->handshake_stage) { case HANDSHAKE_DENIED: server_client_drop(server, client); SESSION("handshake failed. dropping"); break; case HANDSHAKE_ACCEPTED: // Notify client of any buffered data if (buffer_read_avail(&client->read_buffer) > 0) { report_read = true; } break; } } if (client->handshake_stage == HANDSHAKE_ACCEPTED && buffer_read_avail(&client->read_buffer) > 0 && server->flags & SF_PARTIAL_READ) { // re-report previously buffered but un-processed data report_read = true; } if (report_read) { server->read_cb(client, server); } }