Пример #1
0
static void owner_disconnect(DBusConnection *conn, void *user_data)
{
    struct connman_session *session = user_data;

    DBG("session %p, %s died", session, session->owner);

    session_disconnect(session);
}
Пример #2
0
/**
	@brief Disconnect from Jabber, destroy a transport_session, and close its socket.
	@param session Pointer to the transport_session to be destroyed.
	@return 1 if successful, or 0 if not.

	The only error condition is a NULL pointer argument.
*/
int session_free( transport_session* session ) {
	if( ! session )
		return 0;
	else {
		session_disconnect( session );
		return session_discard( session );
	}
}
Пример #3
0
static void test_session_connect_disconnect_notify(struct test_session *session)
{
	enum test_session_state state = get_session_state(session);
	enum test_session_state next_state = state;
	DBusMessage *msg;

	LOG("state %d session %p %s state %d", state, session,
		session->notify_path, session->info->state);

	switch (state) {
	case TEST_SESSION_STATE_0:
		if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
			next_state = TEST_SESSION_STATE_1;
		if (session->info->state == CONNMAN_SESSION_STATE_CONNECTED) {
			LOG("state was already connected, continuing");
			next_state = TEST_SESSION_STATE_2;
		}
		break;
	case TEST_SESSION_STATE_1:
		if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
			next_state = TEST_SESSION_STATE_2;
		break;
	case TEST_SESSION_STATE_2:
		if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
			next_state = TEST_SESSION_STATE_3;
	default:
		break;
	}

	if (state == next_state)
		return;

	set_session_state(session, next_state);

	LOG("next_state %d", next_state);

	switch (next_state) {
	case TEST_SESSION_STATE_1:
		msg = session_connect(session->connection, session);
		g_assert(msg);
		dbus_message_unref(msg);
		return;
	case TEST_SESSION_STATE_2:
		msg = session_disconnect(session->connection, session);
		g_assert(msg);
		dbus_message_unref(msg);
		return;
	case TEST_SESSION_STATE_3:
		util_session_cleanup(session);
		util_idle_call(session->fix, util_quit_loop,
				util_session_destroy);
		return;
	default:
		return;
	}
}
Пример #4
0
static void disconnect_pppoe_ses(void)
{
    int ret;
    warn("Doing disconnect");
    session_disconnect(ses);
    ses->sp.sa_addr.pppoe.sid = 0;
    ret = connect(ses->fd, (struct sockaddr*)&ses->sp,
	    sizeof(struct sockaddr_pppox));

}
Пример #5
0
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
}
Пример #6
0
void session_free (SESSION * session)
{
	session_disconnect (session);

	if (session->dh)
		DH_free (session->dh);

	if (session->rsa)
		RSA_free (session->rsa);

	free (session);
}
Пример #7
0
static void test_session_connect_disconnect_notify(struct test_session *session)
{
	enum test_session_state state = get_session_state(session);
	enum test_session_state next_state = state;
	DBusMessage *msg;

	LOG("state %d session %p %s online %d", state, session,
		session->notify_path, session->info->online);

	switch (state) {
	case TEST_SESSION_STATE_0:
		if (session->info->online == FALSE)
			next_state = TEST_SESSION_STATE_1;
		break;
	case TEST_SESSION_STATE_1:
		if (session->info->online == TRUE)
			next_state = TEST_SESSION_STATE_2;
		break;
	case TEST_SESSION_STATE_2:
		if (session->info->online == FALSE)
			next_state = TEST_SESSION_STATE_3;
	default:
		break;
	}

	if (state == next_state)
		return;

	set_session_state(session, next_state);

	LOG("next_state %d", next_state);

	switch (next_state) {
	case TEST_SESSION_STATE_1:
		msg = session_connect(session->connection, session);
		g_assert(msg != NULL);
		dbus_message_unref(msg);
		return;
	case TEST_SESSION_STATE_2:
		msg = session_disconnect(session->connection, session);
		g_assert(msg != NULL);
		dbus_message_unref(msg);
		return;
	case TEST_SESSION_STATE_3:
		util_session_cleanup(session);
		util_idle_call(session->fix, util_quit_loop,
				util_session_destroy);
		return;
	default:
		return;
	}
}
Пример #8
0
static DBusMessage *destroy_session(DBusConnection *conn,
                                    DBusMessage *msg, void *user_data)
{
    struct connman_session *session = user_data;

    DBG("session %p", session);

    if (ecall_session && ecall_session != session)
        return __connman_error_failed(msg, EBUSY);

    session_disconnect(session);

    return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
Пример #9
0
void session_free (SESSION * session)
{
	session_disconnect (session);

	if (session->dh)
		DH_free (session->dh);

	if (session->rsa)
		RSA_free (session->rsa);

	pthread_cond_destroy(&session->login_cond);
	pthread_mutex_destroy(&session->login_mutex);

	free (session);
}
Пример #10
0
static void test_session_disconnect(struct test_fix *fix)
{
	struct test_session *session;
	DBusMessage *msg;

	util_session_create(fix, 1);
	session = fix->session;

	session->notify_path = g_strdup("/foo");
	session->notify =  test_session_disconnect_notify;
	util_session_init(session);

	msg = session_disconnect(session->connection, session);
	g_assert(msg);
	dbus_message_unref(msg);
}
Пример #11
0
void
cl_ev_disconnect(void)
{
    const char *jid = connection_get_fulljid();
    cons_show("%s logged out successfully.", jid);

    ui_disconnected();
    ui_close_all_wins();
    session_disconnect();
    roster_destroy();
    muc_invites_clear();
    chat_sessions_clear();
    tlscerts_clear_current();
#ifdef HAVE_LIBGPGME
    p_gpg_on_disconnect();
#endif
}
Пример #12
0
static gboolean test_session_disconnect(gpointer data)
{
	struct test_fix *fix = data;
	struct test_session *session;
	DBusMessage *msg;

	util_session_create(fix, 1);
	session = fix->session;

	session->notify_path = g_strdup("/foo");
	session->notify =  test_session_disconnect_notify;
	util_session_init(session);

	msg = session_disconnect(session->connection, session);
	g_assert(msg != NULL);
	dbus_message_unref(msg);

	return FALSE;
}
Пример #13
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;
}
/**
	@brief Disconnect from the Jabber session.
	@param client Pointer to the transport_client.
	@return 0 in all cases.

	If there are any messages still in the queue, they stay there; i.e. we don't free them here.
*/
int client_disconnect( transport_client* client ) {
	if( client == NULL ) { return 0; }
	return session_disconnect( client->session );
}
Пример #15
0
static gint smtp_session_recv_msg(Session *session, const gchar *msg)
{
	SMTPSession *smtp_session = SMTP_SESSION(session);
	gboolean cont = FALSE;

	if (strlen(msg) < 4) {
		log_warning(_("bad SMTP response\n"));
		return -1;
	}

	switch (smtp_session->state) {
	case SMTP_EHLO:
	case SMTP_STARTTLS:
	case SMTP_AUTH:
	case SMTP_AUTH_PLAIN:
	case SMTP_AUTH_LOGIN_USER:
	case SMTP_AUTH_LOGIN_PASS:
	case SMTP_AUTH_CRAM_MD5:
		log_print("ESMTP< %s\n", msg);
		break;
	default:
		log_print("SMTP< %s\n", msg);
		break;
	}

	if (msg[0] == '5' && msg[1] == '0' &&
	    (msg[2] == '4' || msg[2] == '3' || msg[2] == '1')) {
		log_warning(_("error occurred on SMTP session\n"));
		smtp_session->state = SMTP_ERROR;
		smtp_session->error_val = SM_ERROR;
		g_free(smtp_session->error_msg);
		smtp_session->error_msg = g_strdup(msg);
		return -1;
	}

	if (!strncmp(msg, "535", 3)) {
		log_warning(_("error occurred on authentication\n"));
		smtp_session->state = SMTP_ERROR;
		smtp_session->error_val = SM_AUTHFAIL;
		g_free(smtp_session->error_msg);
		smtp_session->error_msg = g_strdup(msg);
		return -1;
	}

	if (msg[0] != '1' && msg[0] != '2' && msg[0] != '3') {
		log_warning(_("error occurred on SMTP session\n"));
		smtp_session->state = SMTP_ERROR;
		smtp_session->error_val = SM_ERROR;
		g_free(smtp_session->error_msg);
		smtp_session->error_msg = g_strdup(msg);
		return -1;
	}

	if (msg[3] == '-')
		cont = TRUE;
	else if (msg[3] != ' ' && msg[3] != '\0') {
		log_warning(_("bad SMTP response\n"));
		smtp_session->state = SMTP_ERROR;
		smtp_session->error_val = SM_UNRECOVERABLE;
		return -1;
	}

	/* ignore all multiline responses except for EHLO */
	if (cont && smtp_session->state != SMTP_EHLO)
		return session_recv_msg(session);

	switch (smtp_session->state) {
	case SMTP_READY:
		if (strstr(msg, "ESMTP"))
			smtp_session->is_esmtp = TRUE;
	case SMTP_CONNECTED:
#if USE_OPENSSL
		if (smtp_session->user || session->ssl_type != SSL_NONE ||
		    smtp_session->is_esmtp)
#else
		if (smtp_session->user || smtp_session->is_esmtp)
#endif
			smtp_ehlo(smtp_session);
		else
			smtp_helo(smtp_session);
		break;
	case SMTP_HELO:
		smtp_from(smtp_session);
		break;
	case SMTP_EHLO:
		smtp_ehlo_recv(smtp_session, msg);
		if (cont == TRUE)
			break;
		if (smtp_session->max_message_size > 0
		&& smtp_session->max_message_size < smtp_session->send_data_len) {
			log_warning(_("Message is too big "
			      "(Maximum size is %s)\n"), 
			      to_human_readable(
			       (off_t)(smtp_session->max_message_size)));

			smtp_session->state = SMTP_ERROR;
			smtp_session->error_val = SM_ERROR;
			return -1;
		}
#if USE_OPENSSL
		if (session->ssl_type == SSL_STARTTLS &&
		    smtp_session->tls_init_done == FALSE) {
			smtp_starttls(smtp_session);
			break;
		}
#endif
		if (smtp_session->user) {
			if (smtp_auth(smtp_session) != SM_OK)
				smtp_from(smtp_session);
		} else
			smtp_from(smtp_session);
		break;
	case SMTP_STARTTLS:
#if USE_OPENSSL
		if (session_start_tls(session) < 0) {
			log_warning(_("can't start TLS session\n"));
			smtp_session->state = SMTP_ERROR;
			smtp_session->error_val = SM_ERROR;
			return -1;
		}
		smtp_session->tls_init_done = TRUE;
		smtp_ehlo(smtp_session);
#endif
		break;
	case SMTP_AUTH:
		smtp_auth_recv(smtp_session, msg);
		break;
	case SMTP_AUTH_LOGIN_USER:
		smtp_auth_login_user_recv(smtp_session, msg);
		break;
	case SMTP_AUTH_PLAIN:
	case SMTP_AUTH_LOGIN_PASS:
	case SMTP_AUTH_CRAM_MD5:
		smtp_from(smtp_session);
		break;
	case SMTP_FROM:
		if (smtp_session->cur_to)
			smtp_rcpt(smtp_session);
		break;
	case SMTP_RCPT:
		if (smtp_session->cur_to)
			smtp_rcpt(smtp_session);
		else
			smtp_data(smtp_session);
		break;
	case SMTP_DATA:
		smtp_send_data(smtp_session);
		break;
	case SMTP_EOM:
		smtp_quit(smtp_session);
		break;
	case SMTP_QUIT:
		session_disconnect(session);
		break;
	case SMTP_ERROR:
	default:
		log_warning(_("error occurred on SMTP session\n"));
		smtp_session->error_val = SM_ERROR;
		return -1;
	}

	if (cont)
		return session_recv_msg(session);

	return 0;
}
Пример #16
0
/*************************************************************************
 *
 * Make a connection -- behaviour depends on callbacks specified in "ses"
 *
 *************************************************************************/
int session_connect(struct session *ses)
{

    struct pppoe_packet *p_out=NULL;
    struct pppoe_packet rcv_packet;
    int ret;


    if(ses->init_disc){
	ret = (*ses->init_disc)(ses, NULL, &p_out);
	if( ret != 0 ) return ret;
    }

    /* main discovery loop */


    while(ses->retransmits <= ses->retries || ses->retries==-1 ){

		fd_set in;
		struct timeval tv;
		FD_ZERO(&in);

		FD_SET(disc_sock,&in);

		if(ses->retransmits>=0){
			++ses->retransmits;
			tv.tv_sec = 1 << ses->retransmits;
			tv.tv_usec = 0;
			ret = select(disc_sock+1, &in, NULL, NULL, &tv);
		}else{
			ret = select(disc_sock+1, &in, NULL, NULL, NULL);
		}

		if( ret == 0 ){
			if((DEB_DISC) && (ses->retransmits <= ses->retries) ){
				poe_dbglog(ses, "Re-sending ...");
			}

			if( ses->timeout ){
				ret = (*ses->timeout)(ses, NULL, &p_out);
				if ( ret != 0 ) {
					poe_info(ses, "returning - %d", ret);
					return ret;
				}

			} else if (p_out) {
				send_disc(ses,p_out);
			}
			continue;
		} 

		ret = recv_disc(ses, &rcv_packet);

		/* Should differentiate between system errors and
		   bad packets and the like... */
		if( ret < 0 && errno != EINTR){

			poe_info(ses, "couldn't rcv packet");
			return -1;
		}

		if (DEB_DISC2)
			syslog(LOG_ERR, "Recieved packet=%x\n", rcv_packet.hdr->code);

		switch (rcv_packet.hdr->code) {

		case PADI_CODE:
		{
			if(ses->rcv_padi){
			ret = (*ses->rcv_padi)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADO_CODE:		/* wait for PADO */
		{
			if(ses->rcv_pado){
			ret = (*ses->rcv_pado)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADR_CODE:
		{
			if(ses->rcv_padr){
			ret = (*ses->rcv_padr)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADS_CODE:
		{
			if(ses->rcv_pads){
			ret = (*ses->rcv_pads)(ses,&rcv_packet,&p_out);

			if( ret != 0){


				return ret;
			}
			}
			break;
		}

		case PADT_CODE:
		{
			if( rcv_packet.hdr->sid != ses->sp.sa_addr.pppoe.sid ){
			--ses->retransmits;
			continue;
			}
			if(ses->rcv_padt){
			ret = (*ses->rcv_padt)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}else{
			poe_error (ses,"connection terminated");
			return (-1);
			}
			break;
		}
		case 0:      /*receiving normal seesion frames*/
		{
			poe_error(ses, "Already in data stream, sending PADT %P\n",
				&rcv_packet);
			if (ses->pppoe_kill) {
				memcpy(&ses->remote,&rcv_packet.addr,
				sizeof(struct sockaddr_ll));
				ses->sp.sa_addr.pppoe.sid = rcv_packet.hdr->sid;
				session_disconnect(ses);
				continue;
			}
			return (-1);
		}
		default:
			poe_error(ses,"invalid packet %P",&rcv_packet);
			return (-1);
		}
    }

	if (ses->retransmits > ses->retries) {
	    	errno = 62;
		return -1;
	}

    return (0);
}
Пример #17
0
void connman_session_destroy(struct connman_session *session)
{
    DBG("session %p", session);

    session_disconnect(session);
}
Пример #18
0
static void test_session_connect_free_ride_notify(struct test_session *session)
{
	struct test_session *session0 = get_session(session, 0);
	struct test_session *session1 = get_session(session, 1);
	enum test_session_state state = get_session_state(session);
	enum test_session_state next_state = state;
	DBusMessage *msg;

	LOG("state %d session %p %s state %d", state, session,
		session->notify_path, session->info->state);

	switch (state) {
	case TEST_SESSION_STATE_0:
		if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
				&& session1->info->state ==
					CONNMAN_SESSION_STATE_DISCONNECTED) {
			next_state = TEST_SESSION_STATE_1;
		}

		break;
	case TEST_SESSION_STATE_1:
		if (session0->info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
				session1->info->state >=
					CONNMAN_SESSION_STATE_CONNECTED) {
			next_state = TEST_SESSION_STATE_2;
		}

		break;
	case TEST_SESSION_STATE_2:
		if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
				&& session1->info->state ==
					CONNMAN_SESSION_STATE_DISCONNECTED) {
			next_state = TEST_SESSION_STATE_3;
		}

		break;
	case TEST_SESSION_STATE_3:

		return;
	}

	if (state == next_state)
		return;

	set_session_state(session, next_state);

	LOG("next_state %d", next_state);

	switch (next_state) {
	case TEST_SESSION_STATE_0:

		return;
	case TEST_SESSION_STATE_1:
		msg = session_connect(session0->connection, session0);
		g_assert(msg != NULL);
		dbus_message_unref(msg);

		return;

	case TEST_SESSION_STATE_2:
		msg = session_disconnect(session0->connection, session0);
		g_assert(msg != NULL);
		dbus_message_unref(msg);

		return;
	case TEST_SESSION_STATE_3:
		util_session_cleanup(session0);
		util_session_cleanup(session1);

		util_idle_call(session0->fix, util_quit_loop,
				util_session_destroy);

		return;
	}
}
Пример #19
0
static gint pop3_session_recv_msg(Session *session, const gchar *msg)
{
	Pop3Session *pop3_session = POP3_SESSION(session);
	Pop3ErrorValue val = PS_SUCCESS;
	const gchar *body;

	body = msg;
	if (pop3_session->state != POP3_GETRANGE_UIDL_RECV &&
	    pop3_session->state != POP3_GETSIZE_LIST_RECV) {
		val = pop3_ok(pop3_session, msg);
		if (val != PS_SUCCESS) {
			if (val != PS_NOTSUPPORTED) {
				pop3_session->state = POP3_ERROR;
				return -1;
			}
		}

		if (*body == '+' || *body == '-')
			body++;
		while (g_ascii_isalpha(*body))
			body++;
		while (g_ascii_isspace(*body))
			body++;
	}

	switch (pop3_session->state) {
	case POP3_READY:
	case POP3_GREETING:
		pop3_greeting_recv(pop3_session, body);
#ifdef USE_GNUTLS
		if (pop3_session->ac_prefs->ssl_pop == SSL_STARTTLS)
			val = pop3_stls_send(pop3_session);
		else
#endif
		if (pop3_session->ac_prefs->use_apop_auth)
			val = pop3_getauth_apop_send(pop3_session);
		else
			val = pop3_getauth_user_send(pop3_session);
		break;
#ifdef USE_GNUTLS
	case POP3_STLS:
		if (pop3_stls_recv(pop3_session) != PS_SUCCESS)
			return -1;
		if (pop3_session->ac_prefs->use_apop_auth)
			val = pop3_getauth_apop_send(pop3_session);
		else
			val = pop3_getauth_user_send(pop3_session);
		break;
#endif
	case POP3_GETAUTH_USER:
		val = pop3_getauth_pass_send(pop3_session);
		break;
	case POP3_GETAUTH_PASS:
	case POP3_GETAUTH_APOP:
		if (!pop3_session->pop_before_smtp)
			val = pop3_getrange_stat_send(pop3_session);
		else
			val = pop3_logout_send(pop3_session);
		break;
	case POP3_GETRANGE_STAT:
		if (pop3_getrange_stat_recv(pop3_session, body) < 0)
			return -1;
		if (pop3_session->count > 0)
			val = pop3_getrange_uidl_send(pop3_session);
		else
			val = pop3_logout_send(pop3_session);
		break;
	case POP3_GETRANGE_LAST:
		if (val == PS_NOTSUPPORTED)
			pop3_session->error_val = PS_SUCCESS;
		else if (pop3_getrange_last_recv(pop3_session, body) < 0)
			return -1;
		if (pop3_session->cur_msg > 0)
			val = pop3_getsize_list_send(pop3_session);
		else
			val = pop3_logout_send(pop3_session);
		break;
	case POP3_GETRANGE_UIDL:
		if (val == PS_NOTSUPPORTED) {
			pop3_session->error_val = PS_SUCCESS;
			val = pop3_getrange_last_send(pop3_session);
		} else {
			pop3_session->state = POP3_GETRANGE_UIDL_RECV;
			session_recv_data(session, 0, ".\r\n");
		}
		break;
	case POP3_GETSIZE_LIST:
		pop3_session->state = POP3_GETSIZE_LIST_RECV;
		session_recv_data(session, 0, ".\r\n");
		break;
	case POP3_RETR:
		pop3_session->state = POP3_RETR_RECV;
		session_recv_data(session, 0, ".\r\n");
		break;
	case POP3_TOP:
		if (val == PS_NOTSUPPORTED) {
			pop3_session->error_val = PS_SUCCESS;
		} else {
			pop3_session->state = POP3_TOP_RECV;
			session_recv_data(session, 0, ".\r\n");
		}
		break;
	case POP3_DELETE:
		pop3_delete_recv(pop3_session);
		if (pop3_session->cur_msg == pop3_session->count)
			val = pop3_logout_send(pop3_session);
		else {
			pop3_session->cur_msg++;
			if (pop3_lookup_next(pop3_session) == POP3_ERROR)
				return -1;
		}
		break;
	case POP3_LOGOUT:
		pop3_session->state = POP3_DONE;
		session_disconnect(session);
		break;
	case POP3_ERROR:
	default:
		return -1;
	}

	return val == PS_SUCCESS?0:-1;
}
Пример #20
0
dk_session_t *
smtp_connect (char * host1, caddr_t * err_ret, caddr_t sender, caddr_t recipient, caddr_t msg_body)
{
  volatile int rc, inx, len, addr, at;
  dk_session_t * volatile ses = dk_session_allocate (SESCLASS_TCPIP);
  caddr_t cmd = NULL;
  char resp [1024];
  char tmp [1024], *ptmp;
  char c;
  caddr_t volatile hf = NULL, host;

  if (!strchr (host1, ':'))
    {
      host = dk_alloc_box (strlen (host1) + 4, DV_SHORT_STRING);
      strcpy_box_ck (host, host1);
      strcat_box_ck (host, ":25");
    }
  else
    {
      host = box_dv_short_string (host1);
    }

  rc = session_set_address (ses->dks_session, host);
  dk_free_box (host); host = NULL;

  if (SER_SUCC != rc)
    {
      PrpcSessionFree (ses);
      *err_ret = srv_make_new_error ("2E000", "SM002", "Cannot resolve host in smtp_send");
      return NULL;
    }
  rc = session_connect (ses->dks_session);
  if (SER_SUCC != rc)
    {
      if (rc != SER_NOREC)
	session_disconnect (ses->dks_session);
      PrpcSessionFree (ses);
      *err_ret = srv_make_new_error ("08001", "SM003", "Cannot connect in smtp_send");
      return NULL;
    }


  cmd = dk_alloc_box (MAX (MAX (box_length(sender), box_length(recipient)), 1000) + 24, DV_LONG_STRING);

  /* get initial line */
  IS_OK_GO (ses, resp, rc, RESP_OK)
  /* send HELO */
  if (gethostname (tmp, sizeof (tmp)))
    strcpy_ck (tmp, "localhost");
  snprintf (cmd, box_length (cmd), "HELO %s\r\n", tmp);
  /*WRITE_CMD (ses, rc, "HELO virtuoso.mail\r\n");*/
  WRITE_CMD (ses, rc, cmd);
  IS_OK_GO (ses, resp, rc, RESP_OK)

  /* send SENDER */
  len = box_length (sender);
  ptmp = tmp;
  addr = -1;
  at = 0;
  for (inx = 0; inx < len; inx++)
    {
      c = sender [inx];
      if (c == '<')
	addr = 1;
      else if (c == '>' && addr == 1)
	addr = 2;
      else if (c == '>' && addr == -1)
	{
	  strcpy_ck (resp, "Unbalanced <...> in sender e-mail address.");
	  goto error_end;
	}
      else if (c == '@')
	at = 1;
      if (((ptmp - tmp) < sizeof(tmp)) && (addr == 1 || addr == 2))
	*ptmp++ = c;
      else if ((ptmp - tmp) >= sizeof(tmp))
	{
	  strcpy_ck (resp, "Sender\'s e-mail address is too long.");
	  goto error_end;
	}

      if (addr == 2)
	{
	  *ptmp = 0;
	  snprintf (cmd, box_length (cmd), "MAIL FROM: %s\r\n", tmp);
	  WRITE_CMD (ses, rc, cmd);
	  IS_OK_GO (ses, resp, rc, RESP_OK)
	  break;
	}
    }