void alloc() { if (session) smtp_destroy_session(session); // create. session = smtp_create_session(); message = smtp_add_message(session); // set server. smtp_set_server(session, d_owner->server.c_str()); // set auth. if (authctx) auth_destroy_context(authctx); authctx = auth_create_context(); // set auth. auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0); auth_set_interact_cb (authctx, authinteract, d_owner); // set passwd. smtp_starttls_set_password_cb(tlsinteract, d_owner); smtp_set_eventcb(session, event_cb, d_owner); smtp_auth_set_context(session, authctx); smtp_set_messagecb(message, readlinefp_cb, d_owner); }
/** * Send a message to the specified remote node. * * @param tsession the GNUNET_MessageHello identifying the remote node * @param msg what to send * @param size the size of the message * @param important is this message important enough to override typical limits? * @return GNUNET_SYSERR on error, GNUNET_OK on success */ static int api_send (GNUNET_TSession * tsession, const void *msg, const unsigned int size, int important) { const GNUNET_MessageHello *hello; const EmailAddress *haddr; char *m; char *filter; char *fvalue; SMTPMessage *mp; struct GetMessageClosure gm_cls; smtp_session_t session; smtp_message_t message; smtp_recipient_t recipient; #define EBUF_LEN 128 char ebuf[EBUF_LEN]; GNUNET_CronTime now; if (smtp_shutdown == GNUNET_YES) return GNUNET_SYSERR; if ((size == 0) || (size > smtpAPI.mtu)) { GNUNET_GE_BREAK (ectx, 0); return GNUNET_SYSERR; } now = GNUNET_get_time (); if ((important != GNUNET_YES) && ((now - last_transmission) * rate_limit) < GNUNET_CRON_HOURS) return GNUNET_NO; /* rate too high */ last_transmission = now; hello = (const GNUNET_MessageHello *) tsession->internal; if (hello == NULL) return GNUNET_SYSERR; GNUNET_mutex_lock (lock); session = smtp_create_session (); if (session == NULL) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, _("SMTP: `%s' failed: %s.\n"), "smtp_create_session", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if (0 == smtp_set_server (session, smtp_server_name)) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE, _("SMTP: `%s' failed: %s.\n"), "smtp_set_server", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } haddr = (const EmailAddress *) &hello[1]; message = smtp_add_message (session); if (message == NULL) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_add_message", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } smtp_set_header (message, "To", NULL, haddr->senderAddress); smtp_set_header (message, "From", NULL, email); filter = GNUNET_strdup (haddr->filter); fvalue = strstr (filter, ": "); GNUNET_GE_ASSERT (NULL, NULL != fvalue); fvalue[0] = '\0'; fvalue += 2; if (0 == smtp_set_header (message, filter, fvalue)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_set_header", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); GNUNET_free (filter); return GNUNET_SYSERR; } GNUNET_free (filter); m = GNUNET_malloc (size + sizeof (SMTPMessage)); GNUNET_memcpy (m, msg, size); mp = (SMTPMessage *) &m[size]; mp->header.size = htons (size + sizeof (SMTPMessage)); mp->header.type = htons (0); mp->sender = *core_api->my_identity; gm_cls.ebody = NULL; gm_cls.pos = 0; gm_cls.esize = GNUNET_STRINGS_base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody); GNUNET_free (m); if (0 == smtp_size_set_estimate (message, gm_cls.esize)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_size_set_estimate", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); } if (0 == smtp_set_messagecb (message, &get_message, &gm_cls)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_set_messagecb", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); GNUNET_free (gm_cls.ebody); return GNUNET_SYSERR; } recipient = smtp_add_recipient (message, haddr->senderAddress); if (recipient == NULL) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_add_recipient", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); return GNUNET_SYSERR; } if (0 == smtp_start_session (session)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, _("SMTP: `%s' failed: %s.\n"), "smtp_start_session", smtp_strerror (smtp_errno (), ebuf, EBUF_LEN)); smtp_destroy_session (session); GNUNET_mutex_unlock (lock); GNUNET_free (gm_cls.ebody); return GNUNET_SYSERR; } if (stats != NULL) stats->change (stat_bytesSent, size); if (core_api->load_monitor != NULL) GNUNET_network_monitor_notify_transmission (core_api->load_monitor, GNUNET_ND_UPLOAD, gm_cls.esize); smtp_message_reset_status (message); /* this is needed to plug a 28-byte/message memory leak in libesmtp */ smtp_destroy_session (session); GNUNET_mutex_unlock (lock); GNUNET_free (gm_cls.ebody); return GNUNET_OK; }
/* * Back-end function to actually send the email */ static int send_email(char *msg) { int i, err = PMIX_SUCCESS; char *str = NULL; char *errmsg = NULL; struct sigaction sig, oldsig; bool set_oldsig = false; smtp_session_t session = NULL; smtp_message_t message = NULL; message_status_t ms; pmix_plog_smtp_component_t *c = &mca_plog_smtp_component; if (NULL == c->to_argv) { c->to_argv = pmix_argv_split(c->to, ','); if (NULL == c->to_argv || NULL == c->to_argv[0]) { return PMIX_ERR_OUT_OF_RESOURCE; } } ms.sent_flag = SENT_NONE; ms.prev_string = NULL; ms.msg = msg; /* Temporarily disable SIGPIPE so that if remote servers timeout or hang up on us, it doesn't kill this application. We'll restore the original SIGPIPE handler when we're done. */ sig.sa_handler = SIG_IGN; sigemptyset(&sig.sa_mask); sig.sa_flags = 0; sigaction(SIGPIPE, &sig, &oldsig); set_oldsig = true; /* Try to get a libesmtp session. If so, assume that libesmtp is happy and proceeed */ session = smtp_create_session(); if (NULL == session) { err = PMIX_ERR_NOT_SUPPORTED; errmsg = "stmp_create_session"; goto error; } /* Create the message */ message = smtp_add_message(session); if (NULL == message) { err = PMIX_ERROR; errmsg = "stmp_add_message"; goto error; } /* Set the SMTP server (yes, it's a weird return status!) */ asprintf(&str, "%s:%d", c->server, c->port); if (0 == smtp_set_server(session, str)) { err = PMIX_ERROR; errmsg = "stmp_set_server"; goto error; } free(str); str = NULL; /* Add the sender */ if (0 == smtp_set_reverse_path(message, c->from_addr)) { err = PMIX_ERROR; errmsg = "stmp_set_reverse_path"; goto error; } /* Set the subject and some headers */ asprintf(&str, "PMIx SMTP Plog v%d.%d.%d", c->super.base.pmix_mca_component_major_version, c->super.base.pmix_mca_component_minor_version, c->super.base.pmix_mca_component_release_version); if (0 == smtp_set_header(message, "Subject", c->subject) || 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1) || 0 == smtp_set_header(message, "To", NULL, NULL) || 0 == smtp_set_header(message, "From", (NULL != c->from_name ? c->from_name : c->from_addr), c->from_addr) || 0 == smtp_set_header(message, "X-Mailer", str) || 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1)) { err = PMIX_ERROR; errmsg = "smtp_set_header"; goto error; } free(str); str = NULL; /* Add the recipients */ for (i = 0; NULL != c->to_argv[i]; ++i) { if (NULL == smtp_add_recipient(message, c->to_argv[i])) { err = PMIX_ERR_OUT_OF_RESOURCE; errmsg = "stmp_add_recipient"; goto error; } } /* Set the callback to get the message */ if (0 == smtp_set_messagecb(message, message_cb, &ms)) { err = PMIX_ERROR; errmsg = "smtp_set_messagecb"; goto error; } /* Send it! */ if (0 == smtp_start_session(session)) { err = PMIX_ERROR; errmsg = "smtp_start_session"; goto error; } /* Fall through */ error: if (NULL != str) { free(str); } if (NULL != session) { smtp_destroy_session(session); } /* Restore the SIGPIPE handler */ if (set_oldsig) { sigaction(SIGPIPE, &oldsig, NULL); } if (PMIX_SUCCESS != err) { int e; char em[256]; e = smtp_errno(); smtp_strerror(e, em, sizeof(em)); pmix_show_help("help-pmix-plog-smtp.txt", "send_email failed", true, "libesmtp library call failed", errmsg, em, e, msg); } return err; }