Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
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);
}
Пример #6
0
Файл: pop.c Проект: ctubio/claws
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);
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #17
0
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));
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
/**
 * 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);
	}
}