static gint c2_smtp_connect (C2SMTP *smtp, C2NetObjectByte **byte) { gchar *ip = NULL; gchar *buffer = NULL; if(!c2_net_object_is_offline(C2_NET_OBJECT(smtp), *byte) && smtp->flags==C2_SMTP_DO_PERSIST) return 0; if(!(*byte = c2_net_object_run(C2_NET_OBJECT(smtp)))) { c2_smtp_set_error(smtp, _("Unable to connect to SMTP server")); g_free(ip); return -1; } if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, *byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, *byte); return -1; } if(!c2_strneq(buffer, "220", 3)) { c2_smtp_set_error(smtp, _("SMTP server was not friendly on our connect! May not be RFC compliant")); g_free(buffer); smtp_disconnect(smtp, *byte); return -1; } if(strstr(buffer, "ESMTP") == NULL) { g_free(buffer); if(c2_smtp_send_helo(smtp, *byte, FALSE) < 0) return -1; } else { g_free(buffer); if(c2_smtp_send_helo(smtp, *byte, TRUE) < 0) return -1; } return 0; }
/*Perform a disconnect from the server*/ void SMTP_CancelThread( void * dummy ) { int l_nReturn = smtp_disconnect( g_pClient ); printf( "Inside CancelThread\n" ); if ( l_nReturn != NSMAIL_OK ) { printf( "smtptest.c::SMTP_CancelThread" ); return; } }
status_t SmtpTransport::Disconnect( void ) { status_t nError; if( false == m_bIsConnected ) return ENOTCONN; if( NULL == m_psSession ) return EINVAL; nError = smtp_disconnect( m_psSession ); if( nError != 0 ) return nError; nError = smtp_destroy_session( m_psSession ); m_psSession = NULL; m_bIsConnected = false; return nError; }
int main(int argc, char *argv[]) { /* Win32 stuff */ #ifdef _WIN32 WSADATA wsa; #endif if (argc == 1) return 0; if (argc == 3 && !strcmp(argv[2], "--debug")) smtp_debug = 1; char *server = strtok(argv[1], ":"), *aport; short port; if ((aport = strtok(NULL, ""))) port = atoi(aport); else port = 25; if (!server) { alog("No Server"); /* Bad, bad, bad. This was a return from main with no value! -GD */ return 0; } else alog("SMTP: server %s port %d",server,port); /* The WSAStartup function initiates use of WS2_32.DLL by a process. */ /* guessing we can skip it under *nix */ #ifdef _WIN32 if (WSAStartup(MAKEWORD(1, 1), &wsa)) return 0; #endif char buf[8192]; bool headers_done = false; /* Read the message and parse it */ while (fgets(buf, 8192, stdin)) { if (smtp_is_header(buf) && !headers_done) { smail.smtp_headers.push_back(strip(buf) + "\r\n"); std::string header, value; smtp_parse_header(buf, header, value); if (header == "From:") { alog("SMTP: from: %s", value.c_str()); smail.from = value; } else if (header == "To:") { alog("SMTP: to: %s", value.c_str()); smtp_set_to(value); } else if (smtp_is_end(buf)) break; else { headers_done = true; smail.smtp_body.push_back(strip(buf) + "\r\n"); } } else smail.smtp_body.push_back(strip(buf) + "\r\n"); } if (!smtp_connect(server, port)) { alog("SMTP: failed to connect to %s:%d", server, port); return 0; } if (!smtp_send_email()) { alog("SMTP: error during sending of mail"); return 0; } smtp_disconnect(); return 1; }
static gint c2_smtp_send_message_contents(C2SMTP *smtp, C2NetObjectByte *byte, C2Message *message, const gint id) { /* This function sends the message body so that there is no * bare 'LF' and that all '\n' are sent as '\r\n' as well * as insuring that BCC fields and X-CronosII fields are * hidden as well */ gchar *ptr, *start, *buf, *contents = message->header; guint len, sent = 0; len = strlen(message->body) + 2 + strlen(message->header); gtk_signal_emit(GTK_OBJECT(smtp), signals[SMTP_UPDATE], id, len, 0); while(1) { for(ptr = start = contents; *ptr != '\0'; ptr++) { if(start == ptr && contents == message->header) { /* if this is the BCC and C2 internal headers, don't send them! */ if(c2_strneq(ptr, "BCC: ", 4) || c2_strneq(ptr, "X-CronosII", 10)) { for( ; *ptr != '\n' && *(ptr+1) != '\0'; ptr++) sent++; sent++; start = *ptr == '\0' ? NULL : ptr + 1; continue; } } if(*ptr == '\n' || *(ptr+1) == '\0') { if (*(ptr+1) == '\0') buf = g_strdup (start); else buf = g_strndup (start, ptr - start); if (c2_net_object_send (C2_NET_OBJECT(smtp), byte, "%s\r\n", buf) < 0) { c2_smtp_set_error (smtp, SOCK_WRITE_FAILED); g_free (buf); smtp_disconnect (smtp, byte); return -1; } if(*(ptr+1) == '\0') { sent++; ptr++; } sent += strlen (buf) + 1; gtk_signal_emit (GTK_OBJECT (smtp), signals[SMTP_UPDATE], id, len, sent); g_free (buf); if (*ptr == '\0') ptr--; start = ptr + 1; } } if(contents == message->header) contents = message->body; else if(contents == message->body) break; if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "\r\n") < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); smtp_disconnect(smtp, byte); return -1; } } return 0; }
static gint c2_smtp_send_headers(C2SMTP *smtp, C2NetObjectByte *byte, C2Message *message) { gchar *buffer, *cc; gchar *temp = NULL, *temp2 = NULL; if(!(temp2 = c2_message_get_header_field(message, "From:")) || !(temp = c2_str_get_email(temp2))) { c2_smtp_set_error(smtp, _("Internal C2 Error: Unable to fetch \"From:\" header in email message")); if(temp2) g_free(temp2); smtp_disconnect(smtp, byte); return -1; } if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "MAIL FROM: %s\r\n", temp) < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); smtp_disconnect(smtp, byte); g_free(temp); g_free(temp2); return -1; } g_free(temp2); g_free(temp); if(!(temp = c2_message_get_header_field(message, "To:"))) { c2_smtp_set_error(smtp, _("Internal C2 Error: Unable to fetch \"To:\" header in email message")); return -1; } if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, byte); return -1; } if(!c2_strneq(buffer, "250", 3)) { c2_smtp_set_error(smtp, _("SMTP server did not reply to 'MAIL FROM:' in a friendly way")); g_free(buffer); smtp_disconnect(smtp, byte); return -1; } g_free(buffer); if((cc = c2_message_get_header_field(message, "CC:"))) { buffer = g_strconcat(temp, ",", cc, NULL); g_free(temp); g_free(cc); } else buffer = temp; temp = NULL; if((cc = c2_message_get_header_field(message, "BCC:"))) { buffer = g_strconcat(buffer, ",", cc, NULL); g_free(cc); } if(c2_smtp_send_rcpt(smtp, byte, buffer) < 0) { smtp_disconnect(smtp, byte); return -1; } g_free(buffer); if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "DATA\r\n") < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); smtp_disconnect(smtp, byte); return -1; } if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, byte); return -1; } if(!c2_strneq(buffer, "354", 3)) { c2_smtp_set_error(smtp, _("SMTP server did not reply to 'DATA' in a friendly way")); g_free(buffer); smtp_disconnect(smtp, byte); return -1; } g_free(buffer); return 0; }
static gint c2_smtp_send_helo (C2SMTP *smtp, C2NetObjectByte *byte, gboolean esmtp) { gchar *hostname, *buffer = NULL; /* hostname = c2_net_get_local_hostname(C2_NET_OBJECT(smtp)); */ hostname = g_strdup("localhost.localdomain"); if(!hostname) hostname = g_strdup("localhost.localdomain"); if(esmtp) { if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "EHLO %s\r\n", hostname) < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); g_free(hostname); smtp_disconnect(smtp, byte); return -1; } g_free(hostname); do { /* Put whatever code in here to mark certain special * ESMTP extensions as working if c2 smtp module * uses them and EHLO reports them */ if(buffer) g_free(buffer); if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, byte); return -1; } } while(c2_strneq(buffer+3, "-", 1)); if(!c2_strneq(buffer, "250", 3)) { c2_smtp_set_error(smtp, _("SMTP server did not respond to 'EHLO in a friendly way")); g_free(buffer); smtp_disconnect(smtp, byte); return -1; } g_free(buffer); } else { if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "HELO %s\r\n", hostname) < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); g_free(hostname); smtp_disconnect(smtp, byte); return -1; } g_free(hostname); if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, byte); return -1; } if(!c2_strneq(buffer, "250", 3)) { c2_smtp_set_error(smtp, _("SMTP server did not respond to HELO in a friendly way")); g_free(buffer); smtp_disconnect(smtp, byte); return -1; } g_free(buffer); } return 0; }
gint c2_smtp_send_message (C2SMTP *smtp, C2Message *message, const gint id) { C2NetObjectByte *byte = NULL; gchar *buffer; gtk_object_ref (GTK_OBJECT (message)); smtp->uses++; if(!smtp->in_use.lock) c2_mutex_lock(&smtp->in_use); if(smtp->type == C2_SMTP_REMOTE) { c2_mutex_lock(&smtp->lock); if(smtp->flags & C2_SMTP_DO_PERSIST) byte = smtp->persistent; if(!byte) { if(c2_smtp_connect(smtp, &byte) < 0) { smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } } if(smtp->flags & C2_SMTP_DO_PERSIST) smtp->persistent = byte; else smtp->persistent = NULL; if(smtp->flags & C2_SMTP_DO_NOT_PERSIST) c2_mutex_unlock(&smtp->lock); if(c2_smtp_send_headers(smtp, byte, message) < 0) { smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } if(c2_smtp_send_message_contents(smtp, byte, message, id) < 0) { smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } if(c2_net_object_send(C2_NET_OBJECT(smtp), byte, "\r\n.\r\n") < 0) { c2_smtp_set_error(smtp, SOCK_WRITE_FAILED); smtp_disconnect(smtp, byte); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } if(c2_net_object_read(C2_NET_OBJECT(smtp), &buffer, byte) < 0) { c2_smtp_set_error(smtp, SOCK_READ_FAILED); smtp_disconnect(smtp, byte); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } if(!c2_strneq(buffer, "250", 3)) { c2_smtp_set_error(smtp, _("SMTP server did not respond to our sent message in a friendly way")); g_free(buffer); smtp_disconnect(smtp, byte); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } if(smtp->flags & C2_SMTP_DO_NOT_PERSIST) smtp_disconnect(smtp, byte); else c2_mutex_unlock(&smtp->lock); g_free(buffer); } else if(smtp->type == C2_SMTP_LOCAL) { gchar *file_name, *from, *to, *temp, *cmd; smtp->uses++; if(!smtp->in_use.lock) c2_mutex_lock(&smtp->in_use); file_name = c2_get_tmp_file (NULL); if(c2_smtp_local_write_msg(message, file_name) < 0) { g_free(file_name); c2_smtp_set_error(smtp, _("System Error: Unable to write message to disk for local SMTP command")); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } /* get the proper to and from headers */ if(!(from = c2_message_get_header_field(message, "From: ")) || !(to = c2_smtp_local_get_recepients(message))) { c2_smtp_set_error(smtp, _("Internal C2 Error: Unable to fetch headers in email message")); unlink(file_name); if(from) g_free(from); g_free(file_name); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } cmd = g_strdup(smtp->smtp_local_cmd); temp = cmd; cmd = c2_str_replace_all(cmd, "%m", file_name); g_free(temp); temp = cmd; cmd = c2_str_replace_all(cmd, "%f", from); g_free(temp); temp = cmd; cmd = c2_str_replace_all(cmd, "%t", to); g_free(temp); g_free(to); g_free(from); /* FINALLY execute the command :-) */ if(system(cmd) < 0) { c2_smtp_set_error(smtp, _("Problem running local SMTP command to send messages -- Check SMTP settings")); unlink(file_name); g_free(file_name); g_free(cmd); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, -1); return -1; } gtk_signal_emit(GTK_OBJECT(smtp), signals[SMTP_UPDATE], id, 1, 1); g_free(file_name); g_free(cmd); unlink(file_name); } gtk_object_unref (GTK_OBJECT (message)); smtp->uses--; if(!smtp->uses) c2_mutex_unlock(&smtp->in_use); gtk_signal_emit(GTK_OBJECT(smtp), signals[FINISHED], id, 1); return 0; }
int main( int argc, char *argv[] ) { int ret; struct smtp_session *session; struct smtp_message *message; char *server, *from, *to, *data; int bytes; if( argc < 4 ) { printf("DemoApp [server] [from] [to]\n"); return EXIT_FAILURE; } server = argv[1]; from = argv[2]; to = argv[3]; printf("Connecting to %s\n", server ); session = smtp_create_session( server, SMTP_DEFAULT_PORT, SMTP_DEFAULT_TIMEOUT, 0 ); if( NULL == session ) { printf("smtp_create_session() failed\n"); return EXIT_FAILURE; } ret = smtp_connect( session ); if( ret ) { printf("smtp_connect() failed\n"); printf("%s", session->buffer ); return EXIT_FAILURE; } printf("%s", session->buffer ); data = (char*)malloc( 4096 ); if( NULL == data ) { printf("Couldn't malloc() data, but this is nothing to do with libsmtp!\n"); return EXIT_FAILURE; } printf("Enter the message to be sent. End with CTRL+D\n"); memset( data, 0, 4096 ); for( bytes = 0; bytes < 406; ++bytes ) { int c = getchar(); if( c == EOF ) break; *(data + bytes) = c; } printf("\nMessage to be sent is as follows"); printf("\n--\n%s\n--\n", data ); message = smtp_create_message( from, data ); smtp_add_recipiant( message, to ); ret = smtp_send( session, message ); if( ret ) { printf("smtp_send() failed\n"); printf("%s", session->buffer ); return EXIT_FAILURE; } printf("%s", session->buffer ); smtp_destroy_message( message ); smtp_disconnect( session ); printf("%s", session->buffer ); smtp_destroy_session( session ); return EXIT_SUCCESS; }