From 83d5d370b3a2f99d315022afd2574784bdc892c0 Mon Sep 17 00:00:00 2001 From: bagyenda <> Date: Wed, 27 Oct 2010 06:08:50 +0000 Subject: [PATCH] added smtp sender --- mbuni/ChangeLog | 2 + mbuni/doc/userguide.shtml | 22 +++++++++ mbuni/mmlib/mms_cfg.def | 1 + mbuni/mmlib/mms_util.c | 96 ++++++++++++++++++++++++++++++++++-- mbuni/mmlib/mms_util.h | 6 ++- mbuni/mmsbox/bearerbox.c | 9 ++-- mbuni/mmsbox/mmsbox_cfg.c | 17 +++++++ mbuni/mmsbox/mmsbox_cfg.h | 4 ++ mbuni/mmsc/mmsc_cfg.c | 15 ++++++ mbuni/mmsc/mmsc_cfg.h | 3 ++ mbuni/mmsc/mmsfromemail.c | 2 +- mbuni/mmsc/mmsglobalsender.c | 5 +- 12 files changed, 168 insertions(+), 14 deletions(-) diff --git a/mbuni/ChangeLog b/mbuni/ChangeLog index ce0450b..50b1f44 100644 --- a/mbuni/ChangeLog +++ b/mbuni/ChangeLog @@ -1,3 +1,5 @@ +2010-10-27 P. A. Bagyenda + * Added smtp sender (direct instead of via sendmail command) 2010-10-26 P. A. Bagyenda * Misc bug fixes 2010-10-25 P. A. Bagyenda diff --git a/mbuni/doc/userguide.shtml b/mbuni/doc/userguide.shtml index ae84372..38cf2d5 100644 --- a/mbuni/doc/userguide.shtml +++ b/mbuni/doc/userguide.shtml @@ -805,6 +805,28 @@ lists all the configuration directives. The column Mode     + + + smtp-relay +     + + + + ALL +     + + + + String +     + + SMTP relay host in the form host:port. (If port is + not included, defaults to 25.) If set, mmsbox uses this to relay + all outgoing MM4 and email requests. Otherwise the sendmail + command defined above is used. +     + + storage-directory diff --git a/mbuni/mmlib/mms_cfg.def b/mbuni/mmlib/mms_cfg.def index 4635c19..a79cd9e 100644 --- a/mbuni/mmlib/mms_cfg.def +++ b/mbuni/mmlib/mms_cfg.def @@ -123,6 +123,7 @@ SINGLE_GROUP(mbuni, OCTSTR(mmsbox-cdr-module) OCTSTR(mmsbox-cdr-module-parameters) OCTSTR(mmsc-services) + OCTSTR(smtp-relay) ) MULTI_GROUP(mmsproxy, diff --git a/mbuni/mmlib/mms_util.c b/mbuni/mmlib/mms_util.c index 04b05f4..339c6f6 100644 --- a/mbuni/mmlib/mms_util.c +++ b/mbuni/mmlib/mms_util.c @@ -32,6 +32,8 @@ #include "mms_queue.h" #include "mms_uaprof.h" +static int smtp_send(char *relay_host, int port, Octstr *from, List *to, Octstr *msg); + Octstr *_mms_cfg_getx(mCfg *cfg, mCfgGrp *grp, Octstr *item) { Octstr *v = mms_cfg_get(cfg, grp, item); @@ -529,7 +531,8 @@ static void addmmscname(Octstr *s, Octstr *myhostname) static int send2email(Octstr *to, Octstr *from, Octstr *subject, Octstr *msgid, MIMEEntity *m, int append_hostname, Octstr **error, - char *sendmail_cmd, Octstr *myhostname) + char *sendmail_cmd, Octstr *myhostname, + Octstr *relay_host, int relay_port) { Octstr *s; FILE *f; @@ -601,6 +604,14 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject, mime_replace_headers(m, headers); s = mime_entity_to_octstr(m); + if (relay_host && relay_port > 0) { + List *lto = gwlist_create(); + gwlist_append(lto, octstr_duplicate(to)); + + ret = smtp_send(octstr_get_cstr(relay_host), relay_port, from, lto, s); + gwlist_destroy(lto, (void *)octstr_destroy); + goto done; + } /* * Make the command: Transpose % formatting characters: * f - from address @@ -709,13 +720,87 @@ done: return ret; } +static int smtp_send(char *relay_host, int port, Octstr *from, List *to, Octstr *msg) +{ + int fd = tcpip_connect_to_server(relay_host, port, NULL); + Connection *c; + Octstr *l; + List *xl; + int i, ret = -1, code; + char tbuf[512]; + + if (fd < 0 || (c = conn_wrap_fd(fd,0)) == NULL) + return -1; + + socket_set_blocking(fd,1); /* Because we want each line as it comes */ + + l = conn_read_line(c); /* Get greeting. */ + + if (l == NULL) + goto done; + tbuf[0] = 0; + sscanf(octstr_get_cstr(l), "%*d %128s", tbuf); + octstr_destroy(l); + +#define SANDC(fmt,arg,val,cont) do { \ + Octstr *y, *x = octstr_format(fmt,arg); \ + conn_write(c,x); \ + octstr_destroy(x); \ + if ((y = conn_read_line(c)) == NULL) \ + goto done; \ + sscanf(octstr_get_cstr(y), "%d", &code); \ + octstr_destroy(y); \ + if (code != (val) && !(cont)) \ + goto done; \ + } while (0) \ + + SANDC("HELO %s\r\n", tbuf, 250,0); + SANDC("MAIL FROM:<%S>\r\n", from, 250,0); + + for (i = 0; i\r\n", xto, 250, 1); + + if (code == 250) { + octstr_destroy(xto); /* Sent */ + gwlist_delete(to, i, 1); + i--; + } + } + SANDC("DATA\r\n", 0, 354, 0); + + xl = octstr_split(msg, octstr_imm("\n")); + + while ((l = gwlist_extract_first(xl)) != NULL) { + + if (octstr_get_char(l, 0) == '.') + octstr_insert_char(l, 0, '.'); + + if (octstr_get_char(l, octstr_len(l) - 1) != '\r') + octstr_append_char(l, '\r'); + octstr_append_char(l, '\n'); + + conn_write(c, l); + octstr_destroy(l); + } + + gwlist_destroy(xl, NULL); + SANDC(".\r\n", 0, 250, 0); + conn_write(c, octstr_imm("QUIT\r\n")); + ret = 0; +done: + conn_destroy(c); + return ret; +} int mm_send_to_email(Octstr *to, Octstr *from, Octstr *subject, Octstr *msgid, MIMEEntity *m, int append_hostname, Octstr **error, - char *sendmail_cmd, Octstr *myhostname) + char *sendmail_cmd, Octstr *myhostname, + Octstr *relay_host, int relay_port) { - return send2email(to,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname); + return send2email(to,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname, relay_host, relay_port); } /* Send this message to email recipient. */ @@ -728,7 +813,8 @@ int mms_sendtoemail(Octstr *from, Octstr *to, int trans_smil, char *txt, char *html, int mm4, char *transid, - List *extra_headers) + List *extra_headers, + Octstr *relay_host, int relay_port) { MIMEEntity *m = NULL; List *headers = NULL; @@ -860,7 +946,7 @@ done: if (ret == 0) ret = send2email(to, - from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname); + from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname, relay_host, relay_port); mime_entity_destroy(m); return ret; diff --git a/mbuni/mmlib/mms_util.h b/mbuni/mmlib/mms_util.h index b0f30af..cc22c8b 100644 --- a/mbuni/mmlib/mms_util.h +++ b/mbuni/mmlib/mms_util.h @@ -114,13 +114,15 @@ int mms_sendtoemail(Octstr *from, Octstr *to, char *sendmail_cmd, Octstr *myhostname, int trans_msg, int trans_smil, char *txt, char *html, int mm4, - char *transid, List *extra_headers); + char *transid, List *extra_headers, + Octstr *relay_host, int relay_port); /* Send directly to email. */ int mm_send_to_email(Octstr *to, Octstr *from, Octstr *subject, Octstr *msgid, MIMEEntity *m, int append_hostname, Octstr **error, - char *sendmail_cmd, Octstr *myhostname); + char *sendmail_cmd, Octstr *myhostname, + Octstr *relay_host, int relay_port); /* log to access log. */ void mms_log(char *logmsg, Octstr *from, List *to, diff --git a/mbuni/mmsbox/bearerbox.c b/mbuni/mmsbox/bearerbox.c index c6a4b68..ca62caa 100644 --- a/mbuni/mmsbox/bearerbox.c +++ b/mbuni/mmsbox/bearerbox.c @@ -1631,7 +1631,7 @@ static int sendMsg(MmsEnvelope *e) "", "", 0, e->xqfname, - e->hdrs); + e->hdrs, smtp_relay.host, smtp_relay.port); if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) { new_msgid = e->msgId ? octstr_duplicate(e->msgId) : octstr_create("00001"); /* Fake it */ mmsbox_event_cb(NULL, MM7_TAG_SubmitReq, 1, octstr_imm("1.0"), 200, @@ -1807,7 +1807,7 @@ static int send_mm4_res(int mtype, Octstr *to, Octstr *sender, Octstr *transid, mm_send_to_email(to, sender, octstr_imm(""), msgid, m, 0, &err, sendmail_cmd, - myhostname); + myhostname, smtp_relay.host, smtp_relay.port); if (err) { mms_warning(0, "MM4", NULL, "send.RES reported: %s!", octstr_get_cstr(err)); octstr_destroy(err); @@ -2170,7 +2170,8 @@ static void clean_address(Octstr **addr, int *isphone, Octstr **xproxy) } -static void smtp_process(int fd, Octstr *ip) +static void smtp_process(int fd, Octstr *ip, + Octstr *(*handle_msg)(MIMEEntity *m, Octstr *from, List *to, MmscGrp *mmc)) { enum smtp_state_t {MLISTEN, MFROM, MTO, MDATA,MERROR}; int i, state = MLISTEN; @@ -2367,7 +2368,7 @@ static void smtp_thread(void *unused) struct mm4_req_t *m; while ((m = gwlist_consume(slist)) != NULL) { - smtp_process(m->fd, m->ip); + smtp_process(m->fd, m->ip, handle_msg); octstr_destroy(m->ip); gw_free(m); } diff --git a/mbuni/mmsbox/mmsbox_cfg.c b/mbuni/mmsbox/mmsbox_cfg.c index 9379e1a..587b0d0 100644 --- a/mbuni/mmsbox/mmsbox_cfg.c +++ b/mbuni/mmsbox/mmsbox_cfg.c @@ -67,6 +67,8 @@ struct SendMmsPortInfo sendmms_port = {-1}; struct MmsBoxMTfilter *mt_filter = NULL; +struct SMTPRelay smtp_relay; + /* do nothing func: Vital it returns 0! */ static int do_nothing_func (void) {return 0;} @@ -272,6 +274,20 @@ int mms_load_mmsbox_settings(struct mCfgImpFuncs *cfg_funcs, Octstr *init, sendmms_port.allow_ip = mms_cfg_get(cfg, grp, octstr_imm("allow-ip")); sendmms_port.deny_ip = mms_cfg_get(cfg, grp, octstr_imm("deny-ip")); + if ((s = mms_cfg_get(cfg,grp,octstr_imm("smtp-relay"))) != NULL) { + int x = octstr_search_char(s, ':', 0); + if (x > 0) { + char *xs = octstr_get_cstr(s) + x + 1; + smtp_relay.host = octstr_copy(s, 0, x); + sscanf(xs, "%d", &smtp_relay.port); + if (smtp_relay.port <= 0) + smtp_relay.port = 25; + } else { + smtp_relay.host = octstr_duplicate(s); + smtp_relay.port = 25; + } + octstr_destroy(s); + } /* Get MM4 port */ mms_cfg_get_int(cfg, grp, octstr_imm("mm4-port"), &mm4_port); @@ -298,6 +314,7 @@ int mms_load_mmsbox_settings(struct mCfgImpFuncs *cfg_funcs, Octstr *init, rfs_settings = _mms_cfg_getx(cfg, grp, octstr_imm("resolver-module-parameters")); rfs_data = rfs->mmsbox_resolvermodule_init(rfs_settings ? octstr_get_cstr(rfs_settings) : NULL); + /* Now get sendmms users. */ l = mms_cfg_get_multi(cfg, octstr_imm("send-mms-user")); for (i = 0, n = gwlist_len(l); i < n; i++) { diff --git a/mbuni/mmsbox/mmsbox_cfg.h b/mbuni/mmsbox/mmsbox_cfg.h index ffdfd42..8b3b713 100644 --- a/mbuni/mmsbox/mmsbox_cfg.h +++ b/mbuni/mmsbox/mmsbox_cfg.h @@ -164,6 +164,10 @@ extern MmsBoxResolverFuncStruct *rfs; /* resolver functions. */ extern void *rfs_data; extern Octstr *rfs_settings; +extern struct SMTPRelay { + Octstr *host; + int port; +} smtp_relay; extern MmsBoxCdrFuncStruct *cdrfs; diff --git a/mbuni/mmsc/mmsc_cfg.c b/mbuni/mmsc/mmsc_cfg.c index 14e88b6..410b30a 100644 --- a/mbuni/mmsc/mmsc_cfg.c +++ b/mbuni/mmsc/mmsc_cfg.c @@ -149,6 +149,21 @@ MmscSettings *mms_load_mmsc_settings(Octstr *fname, List **proxyrelays, int skip m->sendmail = _mms_cfg_getx(cfg, grp, octstr_imm("send-mail-prog")); + if ((s = mms_cfg_get(cfg,grp,octstr_imm("smtp-relay"))) != NULL) { + int x = octstr_search_char(s, ':', 0); + if (x > 0) { + char *xs = octstr_get_cstr(s) + x + 1; + m->smtp_relay = octstr_copy(s, 0, x); + sscanf(xs, "%d", &m->smtp_port); + if (m->smtp_port <= 0) + m->smtp_port = 25; + } else { + m->smtp_relay = octstr_duplicate(s); + m->smtp_port = 25; + } + octstr_destroy(s); + } + qdir = _mms_cfg_getx(cfg, grp, octstr_imm("storage-directory")); if (qdir && octstr_len(qdir) >= QFNAMEMAX) mms_warning(0, "mmsc", NULL,"storage-directory name too long. Max length is %d", QFNAMEMAX); diff --git a/mbuni/mmsc/mmsc_cfg.h b/mbuni/mmsc/mmsc_cfg.h index 5ee6285..d7d4aac 100644 --- a/mbuni/mmsc/mmsc_cfg.h +++ b/mbuni/mmsc/mmsc_cfg.h @@ -60,6 +60,9 @@ typedef struct MmscSettings { Octstr *sendmail; + Octstr *smtp_relay; + int smtp_port; + Octstr *global_queuedir, *mm1_queuedir; Octstr *mmbox_rootdir; diff --git a/mbuni/mmsc/mmsfromemail.c b/mbuni/mmsc/mmsfromemail.c index d29848d..1e0c6f7 100644 --- a/mbuni/mmsc/mmsfromemail.c +++ b/mbuni/mmsc/mmsfromemail.c @@ -639,7 +639,7 @@ static void send_mm4_res(int mtype, Octstr *to, Octstr *sender, Octstr *transid, http_destroy_headers(h); mm_send_to_email(to, sender, octstr_imm(""), msgid, m, 0, &err, octstr_get_cstr(sendmail_cmd), - settings->hostname); + settings->hostname, settings->smtp_relay, settings->smtp_port); if (err) { mms_warning(0, "MM4", NULL, "send.RES reported: %s!", octstr_get_cstr(err)); octstr_destroy(err); diff --git a/mbuni/mmsc/mmsglobalsender.c b/mbuni/mmsc/mmsglobalsender.c index db34a15..ede4d0c 100644 --- a/mbuni/mmsc/mmsglobalsender.c +++ b/mbuni/mmsc/mmsglobalsender.c @@ -188,7 +188,7 @@ static int sendMsg(MmsEnvelope *e) settings->hostname, 1, 1, octstr_get_cstr(settings->mms_email_txt), octstr_get_cstr(settings->mms_email_html), 0, e->xqfname, - e->hdrs); + e->hdrs, settings->smtp_relay, settings->smtp_port); if (res == MMS_SEND_QUEUED) res = MMS_SEND_OK; /* queued to email treated same as sent. * XXX - this means DLR requests for emailed messages not supported! @@ -600,7 +600,8 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to, subject ? subject : settings->mms_email_subject, msgid, msg, dlr, error, proxy_sendmail_cmd ? octstr_get_cstr(proxy_sendmail_cmd) : sendmail_cmd, - settings->hostname, 0, 0,NULL,NULL,1, octstr_get_cstr(xtransid), extra_headers); + settings->hostname, 0, 0,NULL,NULL,1, octstr_get_cstr(xtransid), extra_headers, + settings->smtp_relay, settings->smtp_port); octstr_destroy(xtransid); if (x == MMS_SEND_QUEUED && !dlr) /* No confirmed sending, and message was queued successfully... */