/*
This file is part of GNUnet
- (C) 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2003-2013 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
#include "platform.h"
#include "gnunet_util.h"
-#include "gnunet_directories.h"
+#include "gnunet_constants.h"
#include "gnunet_protocols.h"
#include "gnunet_transport.h"
#include "gnunet_stats_service.h"
*/
#define SMTP_MESSAGE_SIZE 65528
-#define DEBUG_SMTP GNUNET_NO
+#define DEBUG_SMTP GNUNET_EXTRA_LOGGING
#define FILTER_STRING_SIZE 64
} EmailAddress;
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Encapsulation of a GNUnet message in the SMTP mail body (before
* base64 encoding).
GNUNET_PeerIdentity sender;
} SMTPMessage;
+GNUNET_NETWORK_STRUCT_END
/* *********** globals ************* */
/**
* apis (our advertised API and the core api )
*/
-static GNUNET_CoreAPIForTransport *coreAPI;
+static GNUNET_CoreAPIForTransport *core_api;
static struct GNUNET_GE_Context *ectx;
static GNUNET_CronTime last_transmission;
-/** ******************** Base64 encoding ***********/
-
-#define FILLCHAR '='
-static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
-
-/**
- * Encode into Base64.
- *
- * @param data the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- * is allocated)
- * @return the size of the output
- */
-static unsigned int
-base64_encode (const char *data, unsigned int len, char **output)
-{
- unsigned int i;
- char c;
- unsigned int ret;
- char *opt;
-
-/* (*output)[ret++] = '\r'; \*/
-#define CHECKLINE \
- if ( (ret % MAX_CHAR_PER_LINE) == 0) { \
- (*output)[ret++] = '\n'; \
- }
- ret = 0;
- opt = GNUNET_malloc (2 + (((len * 4 / 3) + 8) * (MAX_CHAR_PER_LINE + 2)) /
- MAX_CHAR_PER_LINE);
- /* message must start with \r\n for libesmtp */
- *output = opt;
- opt[0] = '\r';
- opt[1] = '\n';
- ret += 2;
- for (i = 0; i < len; ++i)
- {
- c = (data[i] >> 2) & 0x3f;
- opt[ret++] = cvt[(int) c];
- CHECKLINE;
- c = (data[i] << 4) & 0x3f;
- if (++i < len)
- c |= (data[i] >> 4) & 0x0f;
- opt[ret++] = cvt[(int) c];
- CHECKLINE;
- if (i < len)
- {
- c = (data[i] << 2) & 0x3f;
- if (++i < len)
- c |= (data[i] >> 6) & 0x03;
- opt[ret++] = cvt[(int) c];
- CHECKLINE;
- }
- else
- {
- ++i;
- opt[ret++] = FILLCHAR;
- CHECKLINE;
- }
- if (i < len)
- {
- c = data[i] & 0x3f;
- opt[ret++] = cvt[(int) c];
- CHECKLINE;
- }
- else
- {
- opt[ret++] = FILLCHAR;
- CHECKLINE;
- }
- }
- opt[ret++] = FILLCHAR;
- return ret;
-}
-
-#define cvtfind(a)( (((a) >= 'A')&&((a) <= 'Z'))? (a)-'A'\
- :(((a)>='a')&&((a)<='z')) ? (a)-'a'+26\
- :(((a)>='0')&&((a)<='9')) ? (a)-'0'+52\
- :((a) == '+') ? 62\
- :((a) == '/') ? 63 : -1)
-/**
- * Decode from Base64.
- *
- * @param data the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- * is allocated)
- * @return the size of the output
- */
-static unsigned int
-base64_decode (const char *data, unsigned int len, char **output)
-{
- unsigned int i;
- char c;
- char c1;
- unsigned int ret = 0;
-
-#define CHECK_CRLF while (data[i] == '\r' || data[i] == '\n') {\
- GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "ignoring CR/LF\n"); \
- i++; \
- if (i >= len) goto END; \
- }
-
- *output = GNUNET_malloc ((len * 3 / 4) + 8);
-#if DEBUG_SMTP
- GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "base64_decode decoding len=%d\n", len);
-#endif
- for (i = 0; i < len; ++i)
- {
- CHECK_CRLF;
- if (data[i] == FILLCHAR)
- break;
- c = (char) cvtfind (data[i]);
- ++i;
- CHECK_CRLF;
- c1 = (char) cvtfind (data[i]);
- c = (c << 2) | ((c1 >> 4) & 0x3);
- (*output)[ret++] = c;
- if (++i < len)
- {
- CHECK_CRLF;
- c = data[i];
- if (FILLCHAR == c)
- break;
- c = (char) cvtfind (c);
- c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
- (*output)[ret++] = c1;
- }
- if (++i < len)
- {
- CHECK_CRLF;
- c1 = data[i];
- if (FILLCHAR == c1)
- break;
-
- c1 = (char) cvtfind (c1);
- c = ((c << 6) & 0xc0) | c1;
- (*output)[ret++] = c;
- }
- }
-END:
- return ret;
-}
/* ********************* the real stuff ******************* */
if ( (retl == NULL) || (smtp_shutdown == GNUNET_YES)) {\
goto END; \
}\
- if (coreAPI->load_monitor != NULL) \
- GNUNET_network_monitor_notify_transmission(coreAPI->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \
+ if (core_api->load_monitor != NULL) \
+ GNUNET_network_monitor_notify_transmission(core_api->load_monitor, GNUNET_ND_DOWNLOAD, strlen(retl)); \
} while (0)
if ((line[pos] == '\r') || (line[pos] == '\n'))
break; /* empty line => end of message! */
}
- size = base64_decode (line, pos, &out);
+ size = GNUNET_STRINGS_base64_decode (line, pos, &out);
if (size < sizeof (SMTPMessage))
{
GNUNET_GE_BREAK (ectx, 0);
if (ntohs (mp->header.size) != size)
{
GNUNET_GE_LOG (ectx,
- GNUNET_GE_WARNING | GNUNET_GE_BULK |
- GNUNET_GE_USER,
- _
- ("Received malformed message via %s. Ignored.\n"),
+ GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
+ _("Received malformed message via %s. Ignored.\n"),
"SMTP");
#if DEBUG_SMTP
GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
- GNUNET_GE_USER,
- "Size returned by base64=%d, in the msg=%d.\n",
- size, ntohl (mp->size));
+ GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
+ "Size returned by base64=%d, in the msg=%d.\n", size,
+ ntohl (mp->size));
#endif
GNUNET_free (out);
goto END;
}
if (stats != NULL)
stats->change (stat_bytesReceived, size);
- coreMP = GNUNET_malloc (sizeof (GNUNET_TransportPacket));
+ coreMP = GNUNET_new (GNUNET_TransportPacket);
coreMP->msg = out;
coreMP->size = size - sizeof (SMTPMessage);
coreMP->tsession = NULL;
coreMP->sender = mp->sender;
#if DEBUG_SMTP
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
+ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
"SMTP message passed to the core.\n");
#endif
- coreAPI->receive (coreMP);
+ core_api->receive (coreMP);
}
END:
#if DEBUG_SMTP
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
+ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
"SMTP message processed.\n");
#endif
if (fdes != NULL)
maddr = (const EmailAddress *) &hello[1];
if ((ntohs (hello->header.size) !=
sizeof (GNUNET_MessageHello) + ntohs (hello->senderAddressSize)) ||
- (maddr->senderAddress[ntohs (hello->senderAddressSize) - 1 -
- FILTER_STRING_SIZE] != '\0'))
+ (maddr->senderAddress
+ [ntohs (hello->senderAddressSize) - 1 - FILTER_STRING_SIZE] != '\0'))
{
GNUNET_GE_BREAK (ectx, 0);
return GNUNET_SYSERR; /* obviously invalid */
EmailAddress *haddr;
int i;
- GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
- "SMTP", "FILTER",
+ GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "FILTER",
"X-mailer: GNUnet", &filter);
if (NULL == strstr (filter, ": "))
{
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
+ GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
_("SMTP filter string to invalid, lacks ': '\n"));
GNUNET_free (filter);
return NULL;
if (strlen (filter) > FILTER_STRING_SIZE)
{
filter[FILTER_STRING_SIZE] = '\0';
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
+ GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
_("SMTP filter string to long, capped to `%s'\n"), filter);
}
i = (strlen (email) + 8) & (~7); /* make multiple of 8 */
* @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)
+api_send (GNUNET_TSession * tsession, const void *msg, const unsigned int size,
+ int important)
{
const GNUNET_MessageHello *hello;
const EmailAddress *haddr;
{
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_GE_IMMEDIATE, _("SMTP: `%s' failed: %s.\n"),
+ "smtp_create_session", smtp_strerror (smtp_errno (), ebuf,
+ EBUF_LEN));
GNUNET_mutex_unlock (lock);
return GNUNET_SYSERR;
}
{
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));
+ 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;
{
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));
+ 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;
{
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));
+ 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);
mp = (SMTPMessage *) &m[size];
mp->header.size = htons (size + sizeof (SMTPMessage));
mp->header.type = htons (0);
- mp->sender = *coreAPI->my_identity;
+ mp->sender = *core_api->my_identity;
gm_cls.ebody = NULL;
gm_cls.pos = 0;
- gm_cls.esize = base64_encode (m, size + sizeof (SMTPMessage), &gm_cls.ebody);
+ 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));
+ 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));
+ 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);
{
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));
+ 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;
{
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));
+ 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);
}
if (stats != NULL)
stats->change (stat_bytesSent, size);
- if (coreAPI->load_monitor != NULL)
- GNUNET_network_monitor_notify_transmission (coreAPI->load_monitor,
+ 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);
* @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
*/
static int
-api_connect (const GNUNET_MessageHello * hello,
- GNUNET_TSession ** tsessionPtr, int may_reuse)
+api_connect (const GNUNET_MessageHello * hello, GNUNET_TSession ** tsessionPtr,
+ int may_reuse)
{
GNUNET_TSession *tsession;
- tsession = GNUNET_malloc (sizeof (GNUNET_TSession));
+ tsession = GNUNET_new (GNUNET_TSession);
tsession->internal = GNUNET_malloc (GNUNET_sizeof_hello (hello));
tsession->peer = hello->senderIdentity;
memcpy (tsession->internal, hello, GNUNET_sizeof_hello (hello));
if (dispatchThread == NULL)
{
GNUNET_GE_DIE_STRERROR (ectx,
- GNUNET_GE_ADMIN | GNUNET_GE_BULK |
- GNUNET_GE_FATAL, "pthread_create");
+ GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
+ "pthread_create");
return GNUNET_SYSERR;
}
return GNUNET_OK;
* Convert SMTP hello to an IP address (always fails).
*/
static int
-api_hello_to_address (const GNUNET_MessageHello * hello,
- void **sa, unsigned int *sa_len)
+api_hello_to_address (const GNUNET_MessageHello * hello, void **sa,
+ unsigned int *sa_len)
{
return GNUNET_SYSERR;
}
* frequency limits to SMTP in the future!).
*/
static int
-api_test_would_try (GNUNET_TSession * tsession, const unsigned int size,
+api_test_would_try (GNUNET_TSession * tsession, unsigned int size,
int important)
{
return GNUNET_OK; /* we always try... */
* returns the smtp transport API.
*/
GNUNET_TransportAPI *
-inittransport_smtp (GNUNET_CoreAPIForTransport * core)
+inittransport_smtp (struct GNUNET_CoreAPIForTransport * core)
{
-
-
unsigned long long mtu;
struct sigaction sa;
- coreAPI = core;
+ core_api = core;
ectx = core->ectx;
- if (!GNUNET_GC_have_configuration_value (coreAPI->cfg, "SMTP", "EMAIL"))
+ if (!GNUNET_GC_have_configuration_value (core_api->cfg, "SMTP", "EMAIL"))
{
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
+ GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
_
("No email-address specified, can not start SMTP transport.\n"));
return NULL;
}
- GNUNET_GC_get_configuration_value_number (coreAPI->cfg,
- "SMTP",
- "MTU",
- 1200,
+ GNUNET_GC_get_configuration_value_number (core_api->cfg, "SMTP", "MTU", 1200,
SMTP_MESSAGE_SIZE,
SMTP_MESSAGE_SIZE, &mtu);
- GNUNET_GC_get_configuration_value_number (coreAPI->cfg,
- "SMTP",
- "RATELIMIT",
+ GNUNET_GC_get_configuration_value_number (core_api->cfg, "SMTP", "RATELIMIT",
0, 0, 1024 * 1024, &rate_limit);
- stats = coreAPI->service_request ("stats");
+ stats = core_api->service_request ("stats");
if (stats != NULL)
{
- stat_bytesReceived
- = stats->create (gettext_noop ("# bytes received via SMTP"));
+ stat_bytesReceived =
+ stats->create (gettext_noop ("# bytes received via SMTP"));
stat_bytesSent = stats->create (gettext_noop ("# bytes sent via SMTP"));
- stat_bytesDropped
- = stats->create (gettext_noop ("# bytes dropped by SMTP (outgoing)"));
+ stat_bytesDropped =
+ stats->create (gettext_noop ("# bytes dropped by SMTP (outgoing)"));
}
- GNUNET_GC_get_configuration_value_filename (coreAPI->cfg,
- "SMTP",
- "PIPE",
- GNUNET_DEFAULT_DAEMON_VAR_DIRECTORY
- "/smtp-pipe", &pipename);
+ GNUNET_GC_get_configuration_value_filename (core_api->cfg, "SMTP", "PIPE", &pipename);
UNLINK (pipename);
if (0 != mkfifo (pipename, S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH))
{
GNUNET_GE_LOG_STRERROR (ectx,
- GNUNET_GE_ADMIN | GNUNET_GE_BULK |
- GNUNET_GE_FATAL, "mkfifo");
+ GNUNET_GE_ADMIN | GNUNET_GE_BULK | GNUNET_GE_FATAL,
+ "mkfifo");
GNUNET_free (pipename);
- coreAPI->service_release (stats);
+ core_api->service_release (stats);
stats = NULL;
return NULL;
}
GNUNET_GE_LOG_STRERROR (ectx,
GNUNET_GE_ADMIN | GNUNET_GE_BULK |
GNUNET_GE_WARNING, "chmod");
- GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
- "SMTP", "EMAIL", NULL, &email);
+ GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "EMAIL", NULL,
+ &email);
lock = GNUNET_mutex_create (GNUNET_NO);
- GNUNET_GC_get_configuration_value_string (coreAPI->cfg,
- "SMTP",
- "SERVER",
+ GNUNET_GC_get_configuration_value_string (core_api->cfg, "SMTP", "SERVER",
"localhost:25", &smtp_server_name);
sa.sa_handler = SIG_IGN;
sigemptyset (&sa.sa_mask);
GNUNET_free (smtp_server_name);
if (stats != NULL)
{
- coreAPI->service_release (stats);
+ core_api->service_release (stats);
stats = NULL;
}
GNUNET_mutex_destroy (lock);