]> git.mikk.net Git - smtpsink/commitdiff
Cleaned up module interface, and provided hooks in more code.
authorchris mikkelson <chris@mikk.net>
Thu, 2 Apr 2009 04:10:33 +0000 (23:10 -0500)
committerchris mikkelson <chris@mikk.net>
Thu, 2 Apr 2009 04:10:33 +0000 (23:10 -0500)
conn_pool.c
module.c
module_api.c
responses.inc
smtp.c
smtpsink-int.h
smtpsink.c
smtpsink.h

index 906b9584da13c62d0e3b1d424663c75c88123b9e..f631f3bd92ffdb10dbe8e9a8463c1b770d09943c 100644 (file)
@@ -69,7 +69,7 @@ close_conn(struct conn *c)
                free(c->rdata.s);
                bzero(&c->rdata, sizeof(c->rdata));
        }
-       module_resetconn(c);
+       module_close(c);
        if (pthread_mutex_lock(&cp.cpmtx)) assert(0);
        cp.count --;
        STAILQ_INSERT_HEAD(&cp.c_pool, c, c_list);
@@ -96,6 +96,7 @@ listener_loop(void *data)
        struct sockaddr_in addr;
        int addrlen, fd;
        struct linger l = {1,0};
+       int ret;
        
        struct conn *c;
 
@@ -120,9 +121,16 @@ listener_loop(void *data)
                c->peer = addr;
                c->fd = fd;
                io_initconn(c);
-               module_initconn(c);
-               greeting(c);
-               c->state = SMTP_GREET;
+               ret = module_connect(c);
+               if (SSM_ACCEPTED(ret))
+                       c->state = SMTP_GREET;
+               else
+                       c->state = SMTP_CLOSED;
+
+               if (!SSM_RESPONDED(ret)) {
+                       if (SSM_ACCEPTED(ret)) greeting(c);
+                       else respond(c, "421 connection rejected\r\n");
+               }
                if (c->wdata.s) {
                        c->event = EV_WRITE;
                } else {
index 566f2fadd9961214e441269b213850ac715e98a3..94eea33e2be1db407b168a652a263b75ba3e5180 100644 (file)
--- a/module.c
+++ b/module.c
@@ -44,8 +44,8 @@ module_init(char *modulespec)
        if (!mod)
                errx(1, "module %s invalid: %s\n", file, dlerror());
 
-       mod->mod_index = nmod;
-       mod->module_init(t);
+       mod->ssm_module_index = nmod;
+       if (mod->ssm_module_init) mod->ssm_module_init(t);
        
        modlist = realloc(modlist, nmod + 1);
        if (!modlist)
@@ -55,38 +55,43 @@ module_init(char *modulespec)
 }
 
 void
-module_hup(void)
+module_reload(void)
 {
        int i;
        for (i = 0; i < nmod; i++)
-               if (modlist[i]->module_hup)
-                       modlist[i]->module_hup();
+               if (modlist[i]->ssm_module_reload)
+                       modlist[i]->ssm_module_reload();
 }
 
-void
-module_initconn(struct conn *c)
-{
+
+int
+module_connect(struct conn *c) {
+       int i, ret;
        if (!c->priv_data) {
                c->priv_data = calloc(1, nmod * sizeof(void *));
+               if (!c->priv_data) {
+                       respond(c, "451 out of memory\r\n");
+                       return SSM_REJECT;
+               }
+       
+       }
+       for (i = 0; i < nmod; i++) {
+               if (modlist[i]->ssm_connect) {
+                       ret = modlist[i]->ssm_connect(c);
+                       if ((ret & 0x0F) != SSM_PASS) return ret;
+               }
        }
+       return SSM_ACCEPT;
 }
 
-void
-module_resetconn(struct conn *c)
-{
-       int i;
-       for (i = 0; i < nmod; i++)
-               if (modlist[i]->reset_cdata)
-                       modlist[i]->reset_cdata(c);
-}
 
 int
 module_helo(struct conn *c, char *cmd, int len, int argoff)
 {
        int i, ret;
        for (i = 0; i < nmod; i++) {
-               if (modlist[i]->hook_helo) {
-                       ret = modlist[i]->hook_helo(c,cmd,len,argoff);
+               if (modlist[i]->ssm_helo) {
+                       ret = modlist[i]->ssm_helo(c,cmd,len,argoff);
                        if ((ret & 0x0F) != SSM_PASS) return ret;
                }
        }
@@ -99,8 +104,8 @@ module_mail(struct conn *c, char *cmd, int len, int argoff)
 {
        int i, ret;
        for (i = 0; i < nmod; i++) {
-               if (modlist[i]->hook_mail) {
-                       ret = modlist[i]->hook_mail(c,cmd,len,argoff);
+               if (modlist[i]->ssm_mail) {
+                       ret = modlist[i]->ssm_mail(c,cmd,len,argoff);
                        if ((ret & 0x0F) != SSM_PASS) return ret;
                }
        }
@@ -112,8 +117,21 @@ module_rcpt(struct conn *c, char *cmd, int len, int argoff)
 {
        int i, ret;
        for (i = 0; i < nmod; i++) {
-               if (modlist[i]->hook_rcpt) {
-                       ret = modlist[i]->hook_rcpt(c,cmd,len,argoff);
+               if (modlist[i]->ssm_rcpt) {
+                       ret = modlist[i]->ssm_rcpt(c,cmd,len,argoff);
+                       if ((ret & 0x0F) != SSM_PASS) return ret;
+               }
+       }
+       return SSM_ACCEPT;
+}
+
+int
+module_data(struct conn *c, char *cmd, int len, int argoff)
+{
+       int i, ret;
+       for (i = 0; i < nmod; i++) {
+               if (modlist[i]->ssm_enddata) {
+                       ret = modlist[i]->ssm_data(c, cmd, len, argoff);
                        if ((ret & 0x0F) != SSM_PASS) return ret;
                }
        }
@@ -121,26 +139,44 @@ module_rcpt(struct conn *c, char *cmd, int len, int argoff)
 }
 
 void
-module_data(struct conn *c, char *data, int len)
+module_body(struct conn *c, char *data, int len)
 {
        int i;
        for (i = 0; i < nmod; i++) {
-               if (modlist[i]->hook_enddata) {
-                       modlist[i]->hook_data(c, data, len);
+               if (modlist[i]->ssm_body) {
+                       modlist[i]->ssm_body(c, data, len);
                }
        }
 }
 
+
 int
 module_enddata(struct conn *c)
 {
        int i, ret;
        for (i = 0; i < nmod; i++) {
-               if (modlist[i]->hook_enddata) {
-                       ret = modlist[i]->hook_enddata(c);
+               if (modlist[i]->ssm_enddata) {
+                       ret = modlist[i]->ssm_enddata(c);
                        if ((ret & 0x0F) != SSM_PASS) return ret;
                }
        }
        return SSM_ACCEPT;
 }
 
+void
+module_abort(struct conn *c)
+{
+       int i;
+       for (i = 0; i < nmod; i++)
+               if (modlist[i]->ssm_abort)
+                       modlist[i]->ssm_abort(c);
+}
+
+void
+module_close(struct conn *c)
+{
+       int i;
+       for (i = 0; i < nmod; i++)
+               if (modlist[i]->ssm_close)
+                       modlist[i]->ssm_close(c);
+}
index ec0bbf30819261dcd112afbb2190c844c5093732..7a2ec324fdcedf9055c8c9a1f62e7d35b7352963 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <dlfcn.h>
@@ -42,12 +43,12 @@ void *
 ssm_getpriv(struct smtpsink_module *m, struct conn *c)
 {
        assert(c->priv_data);
-       return c->priv_data[m->mod_index];
+       return c->priv_data[m->ssm_module_index];
 }
 
 void
 ssm_setpriv(struct smtpsink_module *m, struct conn *c, void *data)
 {
        assert(c->priv_data);
-       c->priv_data[m->mod_index] = data;
+       c->priv_data[m->ssm_module_index] = data;
 }
index b3b1ed1d53a5cfab4629099bd950904ab265db96..1e15756f4830f4a7f988fe5526fce06f7a88d702 100644 (file)
@@ -22,6 +22,7 @@ static char *rcpt_reject = "553 recipient rejected.\r\n";
 
 /* DATA command */
 static char *data_ok = "354 go ahead\r\n";
+static char *data_reject = "554 data command rejected\r\n";
 
 /* End of DATA (timestamp, random integer) */
 static char *enddata_ok = "250 ok %d qp %d\r\n";
diff --git a/smtp.c b/smtp.c
index b0493e934dbb14f75c0be5e790383ee2bf8e6f5d..8634a2d5d2d35fffd935adf5789d73095abde278 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -86,22 +86,42 @@ static int
 smtpd_rcpt(struct conn *c, char *cmd, int len, int argoff)
 {
        int ret;
-       if (c->state == SMTP_MAIL || c->state == SMTP_RCPT) {
-               ret = module_rcpt(c, cmd, len, argoff);
+       char *resp = rcpt_ok;
+       if (c->state != SMTP_MAIL && c->state != SMTP_RCPT)
+               return respond(c, err_wantmail);
+
+       ret = module_rcpt(c, cmd, len, argoff);
+       if (SSM_ACCEPTED(ret))
                c->state = SMTP_RCPT;
-               return respond(c, rcpt_ok);
+       else
+               resp = rcpt_reject;
+
+       if (SSM_RESPONDED(ret)) {
+               if (c->wdata.s) return 0;
+               return 1;
        }
-       return respond(c, err_wantmail);
+       return respond(c, resp);
 }
 
 static int
 smtpd_data(struct conn *c, char *cmd, int len, int argoff)
 {
+       int ret;
+       char *resp = data_ok;
        if (c->state != SMTP_RCPT)
                return respond(c, err_wantrcpt);
-       c->state = SMTP_DATA;
-       c->dstate = 2;
-       return respond(c, data_ok);
+       ret = module_data(c, cmd, len, argoff);
+       if (SSM_ACCEPTED(ret)) {
+               c->state = SMTP_DATA;
+               c->dstate = 2;
+       } else
+               resp = data_reject;
+       
+       if (SSM_RESPONDED(ret)) {
+               if (c->wdata.s) return 0;
+               return 1;
+       }
+       return respond(c, resp);
 }
 
 static int
@@ -126,6 +146,7 @@ static int
 smtpd_rset(struct conn *c, char *cmd, int len, int argoff)
 {
        c->state = SMTP_RSET;
+       module_abort(c);
        return respond(c, rset_ok);
 }
 
@@ -226,7 +247,7 @@ do_smtp(struct conn  *c, char **buf, int *len)
                        }
                        break;
                }
-               module_data(c, *buf, s - *buf);
+               module_body(c, *buf, s - *buf);
                *len -= s - *buf;
                *buf = s;
                if (c->dstate == 5) return smtpd_enddata(c);
index 8cd64a403b2b908bcf25d01e1a3d5f963524d641..bb60c5706d686ba99b8b6831e2657d18e12e1645 100644 (file)
@@ -21,11 +21,13 @@ extern char *banner_hostname;
 
 /* module hooks */
 extern void module_init(char *);
-extern void module_hup(void);
-extern void module_initconn(struct conn *);
-extern void module_resetconn(struct conn *);
+extern void module_reload(void);
+extern int module_connect(struct conn *);
 extern int module_helo(struct conn *, char *, int, int);
 extern int module_mail(struct conn *, char *, int, int);
 extern int module_rcpt(struct conn *, char *, int, int);
-extern void module_data(struct conn *, char *, int);
+extern int module_data(struct conn *, char *, int, int);
+extern void module_body(struct conn *, char *, int);
 extern int module_enddata(struct conn *);
+extern void module_abort(struct conn *);
+extern void module_close(struct conn *);
index 3bbd394fd3325a9c4838752ce0b88435cf7c5b27..886d9ef8293ea2c1e4c0afcbe94c04074271d1d5 100644 (file)
@@ -33,18 +33,27 @@ sigev_exit(int fd, short event, void *arg)
        exit(0);
 }
 
+static void
+sigev_reload(int fd, short event, void *arg)
+{
+       module_reload();
+}
+
 static void *
 sigloop(void *data)
 {
        struct event_base *base = (struct event_base *)data;
-       struct event sigterm, sigint;
+       struct event sigterm, sigint, sighup;
 
        signal_set(&sigint, SIGINT, sigev_exit, 0);
        event_base_set(base, &sigint);
        signal_set(&sigterm, SIGTERM, sigev_exit, 0);
        event_base_set(base, &sigint);
+       signal_set(&sighup, SIGHUP, sigev_reload, 0);
+       event_base_set(base, &sighup);
        signal_add(&sigint, 0);
        signal_add(&sigterm, 0);
+       signal_add(&sighup, 0);
        event_base_dispatch(base);
        return (void *)base;
 }
index f556f251276d6ae55d0e494eaa3041fff9bd557a..75076ae412ec30a05943b46f688675ffbc347895 100644 (file)
@@ -50,23 +50,20 @@ int respond(struct conn *, const char *, ...);
 #define SSM_RESPONDED(x)       (x & 0x100)
 
 struct smtpsink_module {
-       void (*module_init)(char *);
-       void (*module_hup)(void);
+       unsigned ssm_module_index;
 
-       /* manage connection private data */
-       void (*reset_cdata)(struct conn *);
+       void (*ssm_module_init)(char *);
+       void (*ssm_module_reload)(void);
 
-       /* smtp command hooks */
-       int (*hook_helo)(struct conn *, char *, int, int);
-       int (*hook_mail)(struct conn *, char *, int, int);
-       int (*hook_rcpt)(struct conn *, char *, int, int);
-
-       /* data processing hooks */
-       void (*hook_data)(struct conn *, char *, int);
-       int (*hook_enddata)(struct conn *);
-
-       /* module index (filled in by module_init) */
-       unsigned mod_index;
+       int (*ssm_connect)(struct conn *);
+       int (*ssm_helo)(struct conn *, char *, int, int);
+       int (*ssm_mail)(struct conn *, char *, int, int);
+       int (*ssm_rcpt)(struct conn *, char *, int, int);
+       int (*ssm_data)(struct conn *, char *, int, int);
+       void (*ssm_body)(struct conn *, char *, int);
+       int (*ssm_enddata)(struct conn *);
+       void (*ssm_abort)(struct conn *);
+       void (*ssm_close)(struct conn *);
 };
 
 void *ssm_getpriv(struct smtpsink_module *, struct conn *);