Example #1
0
File: smtp.c Project: gitpan/zxid
/* Called by: */
int smtp_decode_req(struct hi_thr* hit, struct hi_io* io)
{
  struct hi_pdu* req = io->cur_pdu;
  D("smtp_state(%d) scan(%.*s)", io->ad.smtp.state, (int)MIN(7, req->ap - req->scan), req->scan);
  switch (io->ad.smtp.state) {
  case SMTP_START:  return smtp_ehlo(hit, io, req);
  case SMTP_MAIN:   return smtp_mail_from(hit, io, req);
  case SMTP_TO:     return smtp_rcpt_to(hit, io, req);
  case SMTP_MORE0:
  case SMTP_MORE1:
  case SMTP_MORE2:  return smtp_data(hit, io, req);
  case SMTP_WAIT:
  case SMTP_STATUS: D("Unexpected state %x", io->ad.smtp.state);
  case SMTP_END:    return smtp_mail_from(hit, io, req);
  default: NEVERNEVER("impossible SMTP state %d", io->ad.smtp.state);
  }
  return 0;
}
Example #2
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;
}
Example #3
0
/*Attempt to send a message*/
void SMTP_SendThread( void * dummy )
{
    int l_nReturn;
    
    SMTP_lock();

    /*Connect to the SMTP server.*/
    l_nReturn = smtp_connect( g_pClient, g_szServer, 25 );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    /*Send the EHLO command passing in the domain name.*/
    l_nReturn = smtp_ehlo( g_pClient, g_szDomain );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    /*Send the MAIL FROM command.*/
    l_nReturn = smtp_mailFrom( g_pClient, g_szSender, NULL );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    /*Send the RCPT TO command.*/
    l_nReturn = smtp_rcptTo( g_pClient, g_szRecipient, NULL );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    /*Send the DATA command.*/
    l_nReturn = smtp_data( g_pClient );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    /* Send the message.*/
    l_nReturn = smtp_send( g_pClient, g_szData );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_quit( g_pClient );

    if ( l_nReturn != NSMAIL_OK )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    l_nReturn = smtp_processResponses( g_pClient );

    if ( l_nReturn != NSMAIL_OK || g_serverError == TRUE )
    {
        printf( "smtptest.c::SMTP_SendThread" );
        SMTP_unlock();
        return;
    }

    SMTP_unlock();
}
Example #4
0
int
mutt_smtp_send (const ADDRESS* from, const ADDRESS* to, const ADDRESS* cc,
const ADDRESS* bcc, const char *msgfile, int eightbit)
{
        CONNECTION *conn;
        ACCOUNT account;
        const char* envfrom;
        char buf[1024];
        int ret = -1;

/* it might be better to synthesize an envelope from from user and host
 * but this condition is most likely arrived at accidentally */
        if (EnvFrom)
                envfrom = EnvFrom->mailbox;
        else if (from)
                envfrom = from->mailbox;
        else {
                mutt_error (_("No from address given"));
                return -1;
        }

        if (smtp_fill_account (&account) < 0)
                return ret;

        if (!(conn = mutt_conn_find (NULL, &account)))
                return -1;

        Esmtp = eightbit;

        do {
/* send our greeting */
                if (( ret = smtp_open (conn)))
                        break;
                FREE (&AuthMechs);

/* send the sender's address */
                ret = snprintf (buf, sizeof (buf), "MAIL FROM:<%s>", envfrom);
                if (eightbit && mutt_bit_isset (Capabilities, EIGHTBITMIME)) {
                        safe_strncat (buf, sizeof (buf), " BODY=8BITMIME", 15);
                        ret += 14;
                }
                if (DsnReturn && mutt_bit_isset (Capabilities, DSN))
                        ret += snprintf (buf + ret, sizeof (buf) - ret, " RET=%s", DsnReturn);
                safe_strncat (buf, sizeof (buf), "\r\n", 3);
                if (mutt_socket_write (conn, buf) == -1) {
                        ret = smtp_err_write;
                        break;
                }
                if ((ret = smtp_get_resp (conn)))
                        break;

/* send the recipient list */
                if ((ret = smtp_rcpt_to (conn, to)) || (ret = smtp_rcpt_to (conn, cc))
                        || (ret = smtp_rcpt_to (conn, bcc)))
                        break;

/* send the message data */
                if ((ret = smtp_data (conn, msgfile)))
                        break;

                mutt_socket_write (conn, "QUIT\r\n");

                ret = 0;
        }
        while (0);

        if (conn)
                mutt_socket_close (conn);

        if (ret == smtp_err_read)
                mutt_error (_("SMTP session failed: read error"));
        else if (ret == smtp_err_write)
                mutt_error (_("SMTP session failed: write error"));
        else if (ret == smtp_err_code)
                mutt_error (_("Invalid server response"));

        return ret;
}
static gboolean
smtp_transport_send_to_sync (CamelTransport *transport,
                             CamelMimeMessage *message,
                             CamelAddress *from,
                             CamelAddress *recipients,
			     gboolean *out_sent_message_saved,
                             GCancellable *cancellable,
                             GError **error)
{
	CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (transport);
	CamelInternetAddress *cia;
	gboolean has_8bit_parts;
	const gchar *addr;
	gint i, len;

	smtp_debug_print_server_name (CAMEL_SERVICE (transport), "Sending with");

	if (!smtp_transport->connected) {
		g_set_error (
			error, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_NOT_CONNECTED,
			_("Cannot send message: service not connected."));
		return FALSE;
	}

	if (!camel_internet_address_get (CAMEL_INTERNET_ADDRESS (from), 0, NULL, &addr)) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Cannot send message: sender address not valid."));
		return FALSE;
	}

	camel_operation_push_message (cancellable, _("Sending message"));

	/* find out if the message has 8bit mime parts */
	has_8bit_parts = camel_mime_message_has_8bit_parts (message);

	/* If the connection needs a ReSET, then do so */
	if (smtp_transport->need_rset &&
	    !smtp_rset (smtp_transport, cancellable, error)) {
		camel_operation_pop_message (cancellable);
		return FALSE;
	}
	smtp_transport->need_rset = FALSE;

	/* rfc1652 (8BITMIME) requires that you notify the ESMTP daemon that
	 * you'll be sending an 8bit mime message at "MAIL FROM:" time. */
	if (!smtp_mail (
		smtp_transport, addr, has_8bit_parts, cancellable, error)) {
		camel_operation_pop_message (cancellable);
		return FALSE;
	}

	len = camel_address_length (recipients);
	if (len == 0) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Cannot send message: no recipients defined."));
		camel_operation_pop_message (cancellable);
		smtp_transport->need_rset = TRUE;
		return FALSE;
	}

	cia = CAMEL_INTERNET_ADDRESS (recipients);
	for (i = 0; i < len; i++) {
		gchar *enc;

		if (!camel_internet_address_get (cia, i, NULL, &addr)) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Cannot send message: "
				"one or more invalid recipients"));
			camel_operation_pop_message (cancellable);
			smtp_transport->need_rset = TRUE;
			return FALSE;
		}

		enc = camel_internet_address_encode_address (NULL, NULL, addr);
		if (!smtp_rcpt (smtp_transport, enc, cancellable, error)) {
			g_free (enc);
			camel_operation_pop_message (cancellable);
			smtp_transport->need_rset = TRUE;
			return FALSE;
		}
		g_free (enc);
	}

	if (!smtp_data (smtp_transport, message, cancellable, error)) {
		camel_operation_pop_message (cancellable);
		smtp_transport->need_rset = TRUE;
		return FALSE;
	}

	camel_operation_pop_message (cancellable);

	return TRUE;
}
Example #6
0
bool smtp_client::data_begin()
{
	return smtp_data(client_) == 0 ? true : false;
}