Skip to content

Commit

Permalink
Add support for capabilities added by plugins (unused)
Browse files Browse the repository at this point in the history
  • Loading branch information
bruceg committed Jul 13, 2011
1 parent 10a5f5c commit d31184d
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 36 deletions.
9 changes: 7 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
-------------------------------------------------------------------------------
Changes in version 2.00

- This version updates the API to add new features. Plugins compiled
for previous versions of mailfront will not work without recompiling.
- This version updates the plugin API to add new features:

- Capabilities reported by the SMTP EHLO response can be added by
plugins.

Plugins compiled for previous versions of mailfront will not work
without recompiling.

Development of this version has been sponsored by FutureQuest, Inc.
[email protected] http://www.FutureQuest.net/
Expand Down
4 changes: 4 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Plugin: clamav

- Add tests (not sure how to emulate the daemon properly)

Plugin: lua

- Fix hooks that can modify strings to actually allow modification

Plugin: patterns

- Add better MIME attachment discrimination to patterns, instead of
Expand Down
23 changes: 16 additions & 7 deletions mailfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ static const response* handle_init(void)
return 0;
}

const response* handle_helo(str* host)
const response* handle_helo(str* host, str* capabilities)
{
const response* resp;
MODULE_CALL(helo, (host), 0, 0);
MODULE_CALL(helo, (host, capabilities), 0, 0);
session_setstr("helo_domain", host->s);
if (session.backend->helo != 0)
return session.backend->helo(host, capabilities);
return 0;
}

Expand Down Expand Up @@ -188,13 +190,20 @@ int respond_line(unsigned number, int final,
return 1;
}

int respond(const response* resp)
int respond_multiline(unsigned number, int final, const char* msg)
{
const char* msg;
const char* nl;
for (msg = resp->message; (nl = strchr(msg, '\n')) != 0; msg = nl + 1)
respond_line(resp->number, 0, msg, nl-msg);
return respond_line(resp->number, 1, msg, strlen(msg));
while ((nl = strchr(msg, '\n')) != 0) {
if (!respond_line(number, 0, msg, nl-msg))
return 0;
msg = nl + 1;
}
return respond_line(number, final, msg, strlen(msg));
}

int respond(const response* resp)
{
return respond_multiline(resp->number, 1, resp->message);
}

const response* backend_data_block(const char* data, unsigned long len)
Expand Down
5 changes: 3 additions & 2 deletions mailfront.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct plugin
const char* name;
unsigned flags;
const response* (*init)(void);
const response* (*helo)(str*);
const response* (*helo)(str* hostname, str* capabilities);
const response* (*reset)(void);
const response* (*sender)(str*);
const response* (*recipient)(str*);
Expand All @@ -43,7 +43,7 @@ extern const char* getprotoenv(const char*);

/* From mailfront.c */
extern const char UNKNOWN[];
extern const response* handle_helo(str* host);
extern const response* handle_helo(str* host, str* capabilities);
extern const response* handle_reset(void);
extern const response* handle_sender(str* sender);
extern const response* handle_recipient(str* recip);
Expand All @@ -53,6 +53,7 @@ extern const response* handle_message_end(void);
extern int respond(const response*);
extern int respond_line(unsigned number, int final,
const char* msg, unsigned long len);
extern int respond_multiline(unsigned number, int final, const char* msg);
extern const response* backend_data_block(const char* data, unsigned long len);
extern int scratchfile(void);

Expand Down
10 changes: 6 additions & 4 deletions plugin-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ <h2>Hook Functions</h2>
responses to the sender address or data, and after the SMTP
<tt>HELO</tt> command.</dd>

<dt><tt>const response* helo(str* hostname)</tt></dt> <dd>This hook is
called when the SMTP <tt>HELO</tt> or <tt>EHLO</tt> commands are issued.
As yet nothing actually uses the <tt>hostname</tt> string. Other
protocols will not call this hook.</dd>
<dt><tt>const response* helo(str* hostname, str* capabilities)</tt></dt>
<dd>This hook is called when the SMTP <tt>HELO</tt> or <tt>EHLO</tt>
commands are issued. As yet nothing actually uses the <tt>hostname</tt>
string. Other protocols will not call this hook.
The <tt>capabilities</tt> variable contains a list of SMTP EHLO response
capabilities, each followed by a newline.</dd>

<dt><tt>const response* sender(str* address)</tt></dt> <dd>This hook is
called after a sender email address is transmitted by the client, and is
Expand Down
5 changes: 3 additions & 2 deletions plugin-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,12 @@ static const response* reset(void)
return 0;
}

static const response* helo(str* hostname)
static const response* helo(str* hostname, str* capabilities)
{
if (setup("helo")) {
lua_pushlstring(L, hostname->s, hostname->len);
return callit(1);
lua_pushlstring(L, capabilities->s, capabilities->len);
return callit(2);
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion plugin-template.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static const response* init(void)
/* The helo function is called once by the SMTP protocol when either the
* HELO or EHLO command is issued. The parameter is the hostname given
* in the command. */
static const response* helo(str* hostname)
static const response* helo(str* hostname, str* capabilities)
{
return 0;
}
Expand Down
47 changes: 29 additions & 18 deletions protocol-smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static str cmd;
static str arg;
static str addr;
static str params;
static str init_capabilities;

static RESPONSE(no_mail, 503, "5.5.1 You must send MAIL FROM: first");
static RESPONSE(vrfy, 252, "2.5.2 Send some mail, I'll try my best.");
Expand All @@ -42,7 +43,6 @@ static RESPONSE(toobig, 552, "5.2.3 The message would exceed the maximum message
static RESPONSE(toomanyunimp, 503, "5.5.0 Too many unimplemented commands.\n5.5.0 Closing connection.");
static RESPONSE(goodbye, 221, "2.0.0 Good bye.");
static RESPONSE(authenticated, 235, "2.7.0 Authentication succeeded.");
static RESPONSE(ehlo, 250, "8BITMIME\nENHANCEDSTATUSCODES\nPIPELINING");

static int saw_mail = 0;
static int saw_rcpt = 0;
Expand Down Expand Up @@ -126,32 +126,26 @@ static int HELO(void)
{
const response* resp;
if (response_ok(resp = handle_reset()))
resp = handle_helo(&arg);
resp = handle_helo(&arg, &line);
return (resp != 0) ? respond(resp)
: respond_line(250, 1, domain_name.s, domain_name.len);
}

static int EHLO(void)
{
static str auth_resp;
const response* resp;
protocol.name = "ESMTP";
line.len = 0;
if (!response_ok(resp = handle_reset())
|| !response_ok(resp = handle_helo(&arg)))
|| !response_ok(resp = handle_helo(&arg, &line)))
return respond(resp);
if (!str_cat(&line, &init_capabilities)) {
respond(&resp_oom);
return 0;
}

if (!respond_line(250, 0, domain_name.s, domain_name.len)) return 0;
switch (sasl_auth_caps(&auth_resp)) {
case 0: break;
case 1:
if (!respond_line(250, 0, auth_resp.s, auth_resp.len)) return 0;
break;
default: return respond(&resp_internal);
}
if (!str_copys(&line, "SIZE ")) return 0;
if (!str_catu(&line, session_getnum("maxdatabytes", 0))) return 0;
if (!respond_line(250, 0, line.s, line.len)) return 0;
return respond(&resp_ehlo);
return respond_multiline(250, 1, line.s);
}

static void do_reset(void)
Expand Down Expand Up @@ -391,14 +385,31 @@ static int init(void)
if ((tmp = getenv("MAXNOTIMPL")) != 0)
maxnotimpl = strtoul(tmp, 0, 10);

if (!sasl_auth_init(&saslauth)) {
respond(&resp_authfail);
return 1;
}
switch (sasl_auth_caps(&init_capabilities)) {
case 0: break;
case 1: break;
default:
respond(&resp_authfail);
return 1;
}

if (!str_copys(&init_capabilities, "SIZE ")
|| !str_catu(&init_capabilities, session_getnum("maxdatabytes", 0))
|| !str_catc(&init_capabilities, '\n')
|| !str_cats(&init_capabilities, "8BITMIME\nENHANCEDSTATUSCODES\nPIPELINING")) {
respond(&resp_oom);
return 1;
}

return 0;
}

static int mainloop(void)
{
if (!sasl_auth_init(&saslauth))
return respond(&resp_authfail);

if (!respond_line(220, 1, str_welcome.s, str_welcome.len)) return 0;
while (ibuf_getstr_crlf(&inbuf, &line))
if (!smtp_dispatch()) {
Expand Down

0 comments on commit d31184d

Please sign in to comment.