* Sends Error-sending-address-unresolved back to unresolved senders
* Adds detokenizing functionality * Adds a few example billing, resolver and detokenizer librariesmaster
parent
d51dc0d1fb
commit
a695ea217f
|
@ -10,6 +10,7 @@ AC_CONFIG_HEADER([config.h])
|
|||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# Checks for libraries.
|
||||
# FIXME: Replace `main' with a function in `-lcrypto':
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
noinst_LIBRARIES = libmms.a
|
||||
libmms_a_SOURCES = mms_billing.c mms_billing.h mms_msg.c mms_msg.h mms_queue.c mms_queue.h mms_strings.c mms_strings.h mms_uaprof.c mms_uaprof.h mms_util.c mms_util.h mms_resolve.c
|
||||
|
||||
|
||||
plugindir = $(libdir)/mbuni
|
||||
plugin_LTLIBRARIES = libmms_billing_shell.la libmms_resolve_shell.la libmms_resolve_all_local.la libmms_detokenize_shell.la
|
||||
libmms_billing_shell_la_SOURCES = mms_billing_shell.c
|
||||
libmms_resolve_shell_la_SOURCES = mms_resolve_shell.c
|
||||
libmms_resolve_all_local_la_SOURCES = mms_resolve_all_local.c
|
||||
libmms_detokenize_shell_la_SOURCES = mms_detokenize_shell.c
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mms_billing.h"
|
||||
|
||||
static Octstr *script = NULL;
|
||||
|
||||
static void *mms_billingmodule_init(char *settings)
|
||||
{
|
||||
script = octstr_create(settings);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int mms_billingmodule_fini(void *module_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double mms_billmsg(Octstr *from, List *to, unsigned long msg_size, void *module_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (script == NULL || octstr_len(script) == 0)
|
||||
return 0;
|
||||
for (i=0;i<list_len(to);i++) {
|
||||
Octstr *s;
|
||||
s = octstr_format("%s '%s' '%s'", octstr_get_cstr(script), octstr_get_cstr(from), octstr_get_cstr(list_get(to, i)));
|
||||
if (s) {
|
||||
system(octstr_get_cstr(s));
|
||||
octstr_destroy(s);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mms_logcdr(MmsCdrStruct *cdr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The function itself. */
|
||||
MmsBillingFuncStruct mms_billfuncs = {
|
||||
mms_billingmodule_init,
|
||||
mms_logcdr,
|
||||
mms_billmsg,
|
||||
mms_billingmodule_fini
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mms_detokenize.h"
|
||||
#include "mms_util.h"
|
||||
|
||||
static int mms_detokenizer_init(char *settings)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mms_detokenizer_fini(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Octstr *mms_detokenize(Octstr * token)
|
||||
{
|
||||
/* Return the MSISDN matching the token as a new Octstr */
|
||||
return octstr_create("+45xxxxxx");
|
||||
}
|
||||
|
||||
/* The function itself. */
|
||||
MmsTokenize mms_detokenizefuncs = {
|
||||
mms_detokenizer_init,
|
||||
mms_detokenize,
|
||||
mms_detokenize_fini
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef __MMS_DETOKENIZE_INCLUDED__
|
||||
#define __MMS_DETOKENIZE_INCLUDED__
|
||||
|
||||
#include <time.h>
|
||||
#include "gwlib/gwlib.h"
|
||||
|
||||
/* Detokenizer module. This file provides prototypes for all detokenizer functions.
|
||||
* The idea is that for each site a DSO will be created that can resolve a token into an
|
||||
* msisdn. This is useful if you're creating a multioperator setup or if your wap gateway
|
||||
* doesn't pass the MSISDN as a header and you want to secure yourself against MSISDN spoofing
|
||||
*/
|
||||
|
||||
typedef struct MmsDetokenizerFuncStruct {
|
||||
/* This function is called once to initialise the detokenizer module. Return 0 on succeful
|
||||
* initialization.
|
||||
*/
|
||||
int (*mms_detokenizer_init)(char *settings);
|
||||
|
||||
/* Looks up the token and returns the msisdn as a new Octstr.
|
||||
* Return NULL on error, otherwise an Octstr
|
||||
*/
|
||||
Octstr *(*mms_detokenize)(Octstr * token);
|
||||
|
||||
int (*mms_detokenizer_fini)(void);
|
||||
} MmsDetokenizerFuncStruct;
|
||||
|
||||
extern MmsDetokenizerFuncStruct mms_detokenizefuncs; /* The module must expose this symbol. */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mms_detokenize.h"
|
||||
#include "mms_util.h"
|
||||
|
||||
Octstr *script;
|
||||
|
||||
static int mms_detokenizer_init(char *settings)
|
||||
{
|
||||
script = octstr_create(settings);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mms_detokenizer_fini(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Octstr *mms_detokenize(Octstr * token)
|
||||
{
|
||||
Octstr *s;
|
||||
FILE *fp;
|
||||
char buf[4096];
|
||||
|
||||
if (script == NULL || octstr_len(script) == 0)
|
||||
return NULL;
|
||||
|
||||
s = octstr_format("%s '%s'", octstr_get_cstr(script), octstr_get_cstr(token));
|
||||
fp = popen(octstr_get_cstr(s), "r");
|
||||
octstr_destroy(s);
|
||||
fgets(buf, 4096, fp);
|
||||
s = octstr_create(buf);
|
||||
octstr_strip_crlfs(s);
|
||||
pclose(fp);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* The function itself. */
|
||||
MmsDetokenizerFuncStruct mms_detokenizefuncs = {
|
||||
mms_detokenizer_init,
|
||||
mms_detokenize,
|
||||
mms_detokenizer_fini
|
||||
};
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mms_resolve.h"
|
||||
#include "mms_util.h"
|
||||
|
||||
static Octstr *script = NULL;
|
||||
|
||||
static void *mms_resolvermodule_init(char *settings)
|
||||
{
|
||||
script = octstr_imm(settings);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int mms_resolvermodule_fini(void *module_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Octstr *mms_resolve(Octstr * phonenum, void *module_data, void *settings_p, void *proxyrelays_p)
|
||||
{
|
||||
Octstr *s;
|
||||
FILE *fp;
|
||||
char buf[4096];
|
||||
|
||||
if (script == NULL || octstr_len(script) == 0)
|
||||
return 0;
|
||||
|
||||
s = octstr_format("%s '%s' ", octstr_get_cstr(phonenum));
|
||||
fp = popen(octstr_get_cstr(s), "r");
|
||||
octstr_destroy(s);
|
||||
|
||||
fgets(buf, 4096, fp);
|
||||
s = octstr_create(buf);
|
||||
octstr_strip_crlfs(s);
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* The function itself. */
|
||||
MmsResolverFuncStruct mms_resolvefuncs = {
|
||||
mms_resolvermodule_init,
|
||||
mms_resolve,
|
||||
mms_resolvermodule_fini
|
||||
};
|
|
@ -187,6 +187,21 @@ MmsBoxSettings *mms_load_mmsbox_settings(Cfg *cfg)
|
|||
|
||||
m->mms_resolver_module_data = m->mms_resolvefuncs->mms_resolvermodule_init(octstr_get_cstr(m->resolver_params));
|
||||
|
||||
m->detokenizer_params = cfg_getx(grp, octstr_imm("detokenizer-module-parameters"));
|
||||
|
||||
/* Get and load the detokenizer lib if any. */
|
||||
if ((m->mms_detokenizefuncs = load_module(grp, "detokenizer-library", "mms_detokenizefuncs"))) {
|
||||
if (m->mms_detokenizefuncs->mms_detokenizer_init == NULL ||
|
||||
m->mms_detokenizefuncs->mms_detokenize == NULL ||
|
||||
m->mms_detokenizefuncs->mms_detokenizer_fini == NULL)
|
||||
panic(0, "Missing or NULL functions in detokenizer module!");
|
||||
if (m->mms_detokenizefuncs->mms_detokenizer_init(octstr_get_cstr(m->detokenizer_params)))
|
||||
panic(0, "Detokenizer module failed to initialize");
|
||||
} else
|
||||
m->mms_detokenizefuncs = NULL;
|
||||
|
||||
m->allow_ip_type = 0;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -236,7 +251,7 @@ Octstr *mms_makefetchurl(char *qf, Octstr *token,
|
|||
}
|
||||
|
||||
|
||||
Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *msisdn_header)
|
||||
Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *msisdn_header, MmsDetokenizerFuncStruct* detokenizerfuncs)
|
||||
{
|
||||
/* Either we have a WAP gateway header as defined, or we look for
|
||||
* last part of url as our number.
|
||||
|
@ -252,7 +267,12 @@ Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *ms
|
|||
if (l && list_len(l) > 1) {
|
||||
int i, n = list_len(l);
|
||||
Octstr *s;
|
||||
phonenum = octstr_duplicate(list_get(l, list_len(l) - 1));
|
||||
|
||||
if (detokenizerfuncs) {
|
||||
phonenum = detokenizerfuncs->mms_detokenize(list_get(l, list_len(l) - 1));
|
||||
} else {
|
||||
phonenum = octstr_duplicate(list_get(l, list_len(l) - 1));
|
||||
}
|
||||
|
||||
/* After getting it, remove it from the end... */
|
||||
for (i = 0, s = octstr_create(""); i < n-1; i++) {
|
||||
|
@ -262,6 +282,7 @@ Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *ms
|
|||
}
|
||||
octstr_destroy(xsend_url);
|
||||
*send_url = s;
|
||||
|
||||
}
|
||||
if (l)
|
||||
list_destroy(l, (list_item_destructor_t *)octstr_destroy);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mms_msg.h"
|
||||
#include "mms_billing.h"
|
||||
#include "mms_resolve.h"
|
||||
#include "mms_detokenize.h"
|
||||
|
||||
/* Send errors */
|
||||
#define MMS_SEND_OK 0
|
||||
|
@ -63,6 +64,12 @@ typedef struct MmsBoxSettings {
|
|||
MmsResolverFuncStruct *mms_resolvefuncs; /* Link to resolver funcs. */
|
||||
void *mms_resolver_module_data;
|
||||
|
||||
Octstr *detokenizer_params;
|
||||
MmsDetokenizerFuncStruct *mms_detokenizefuncs; /* Link to detokenizer funcs. */
|
||||
void *mms_detokenizer_module_data;
|
||||
|
||||
int allow_ip_type;
|
||||
|
||||
Octstr *prov_notify;
|
||||
Octstr *prov_notify_arg;
|
||||
Octstr *prov_getstatus;
|
||||
|
@ -107,7 +114,7 @@ extern Octstr *mms_getqf_fromtransid(Octstr *transid);
|
|||
extern int mms_decodefetchurl(Octstr *fetch_url,
|
||||
Octstr **qf, Octstr **token);
|
||||
|
||||
Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *msisdn_header);
|
||||
Octstr *mms_find_sender_msisdn(Octstr **send_url, List *request_hdrs, Octstr *msisdn_header, MmsDetokenizerFuncStruct *detokenizerfuncs);
|
||||
Octstr *mms_find_sender_ip(List *request_hdrs, Octstr *ip_header, Octstr *ip, int *isv6);
|
||||
|
||||
extern Octstr *mms_isodate(time_t t);
|
||||
|
|
|
@ -135,15 +135,20 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* Get the sender address. */
|
||||
|
||||
h.base_client_addr = mms_find_sender_msisdn(&h.url, h.headers, settings->wap_gw_msisdn_header);
|
||||
|
||||
|
||||
h.base_client_addr = mms_find_sender_msisdn(&h.url, h.headers, settings->wap_gw_msisdn_header, settings->mms_detokenizefuncs);
|
||||
|
||||
if (!h.base_client_addr) { /* Set to IP sender... XXXX assumes ipv4 only for now*/
|
||||
int ipv6 = 0;
|
||||
h.base_client_addr = mms_find_sender_ip(h.headers,
|
||||
settings->wap_gw_ip_header,
|
||||
h.ip, &ipv6);
|
||||
h.client_addr = octstr_format("%S/TYPE=IPv%s",
|
||||
h.ip, ipv6 ? "6" : "4");
|
||||
if (settings->allow_ip_type) {
|
||||
int ipv6 = 0;
|
||||
h.base_client_addr = mms_find_sender_ip(h.headers,
|
||||
settings->wap_gw_ip_header,
|
||||
h.ip, &ipv6);
|
||||
h.client_addr = octstr_format("%S/TYPE=IPv%s",
|
||||
h.ip, ipv6 ? "6" : "4");
|
||||
} else {
|
||||
h.client_addr = NULL;
|
||||
}
|
||||
} else {
|
||||
normalize_number(octstr_get_cstr(settings->unified_prefix), &h.base_client_addr);
|
||||
h.client_addr = octstr_format("%S/TYPE=PLMN", h.base_client_addr);
|
||||
|
@ -461,8 +466,6 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
http_header_add(rh, "Pragma", "no-cache");
|
||||
http_header_add(rh, "Cache-Control", "no-cache");
|
||||
|
||||
|
||||
|
||||
if (!h->body) { /* A body is required. */
|
||||
http_header_add(rh, "Content-Type", "text/plain");
|
||||
hstatus = HTTP_FORBIDDEN;
|
||||
|
@ -471,8 +474,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
|
||||
goto done;
|
||||
}
|
||||
|
||||
m = mms_frombinary(h->body, h->client_addr);
|
||||
|
||||
m = mms_frombinary(h->body, h->client_addr ? h->client_addr : octstr_imm("") );
|
||||
|
||||
if (!m) {
|
||||
http_header_add(rh, "Content-Type", "text/plain");
|
||||
|
@ -502,42 +505,46 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
Octstr *subject;
|
||||
time_t expiryt, deliveryt;
|
||||
|
||||
Octstr *otransid, *value;
|
||||
Octstr *otransid = NULL, *value = NULL;
|
||||
int dlr;
|
||||
|
||||
|
||||
collect_senddata(mh, &to, &from, &subject, &otransid, &expiryt, &deliveryt);
|
||||
|
||||
/*Delete some headers that must be sent on. */
|
||||
mms_remove_headers(m, "Bcc");
|
||||
mms_remove_headers(m, "X-Mms-Delivery-Time");
|
||||
mms_remove_headers(m, "X-Mms-Expiry");
|
||||
mms_remove_headers(m, "X-Mms-Sender-Visibility");
|
||||
|
||||
if (!h->client_addr) {
|
||||
mresp = mms_sendconf("Error-sending-address-unresolved", "None", octstr_get_cstr(otransid),0);
|
||||
} else {
|
||||
|
||||
value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"));
|
||||
if (value &&
|
||||
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
||||
dlr = 1;
|
||||
else
|
||||
dlr = 0;
|
||||
/*Delete some headers that must be sent on. */
|
||||
mms_remove_headers(m, "Bcc");
|
||||
mms_remove_headers(m, "X-Mms-Delivery-Time");
|
||||
mms_remove_headers(m, "X-Mms-Expiry");
|
||||
mms_remove_headers(m, "X-Mms-Sender-Visibility");
|
||||
|
||||
|
||||
value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"));
|
||||
if (value &&
|
||||
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
||||
dlr = 1;
|
||||
else
|
||||
dlr = 0;
|
||||
|
||||
|
||||
qf = mms_queue_add(from, to, NULL, subject,
|
||||
NULL, NULL, deliveryt, expiryt, m, NULL, dlr,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
|
||||
if (!qf)
|
||||
mresp = mms_sendconf("Error-transient-failure", "None", octstr_get_cstr(otransid),0);
|
||||
else {
|
||||
Octstr *transid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias);
|
||||
mresp = mms_sendconf("Ok", octstr_get_cstr(transid), octstr_get_cstr(otransid),0);
|
||||
qf = mms_queue_add(from, to, NULL, subject,
|
||||
NULL, NULL, deliveryt, expiryt, m, NULL, dlr,
|
||||
octstr_get_cstr(settings->global_queuedir));
|
||||
|
||||
if (!qf)
|
||||
mresp = mms_sendconf("Error-transient-failure", "None", octstr_get_cstr(otransid),0);
|
||||
else {
|
||||
Octstr *transid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias);
|
||||
mresp = mms_sendconf("Ok", octstr_get_cstr(transid), octstr_get_cstr(otransid),0);
|
||||
|
||||
/* Log to access log */
|
||||
mms_log("Received", from, to, msize, transid, NULL, NULL, "MM1", h->ua);
|
||||
/* Log to access log */
|
||||
mms_log("Received", from, to, msize, transid, NULL, NULL, "MM1", h->ua);
|
||||
|
||||
octstr_destroy(transid);
|
||||
octstr_destroy(qf);
|
||||
octstr_destroy(transid);
|
||||
octstr_destroy(qf);
|
||||
}
|
||||
}
|
||||
|
||||
if (otransid)
|
||||
|
@ -885,7 +892,8 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
|
|||
|
||||
if (h->base_client_addr)
|
||||
octstr_destroy(h->base_client_addr);
|
||||
octstr_destroy(h->client_addr);
|
||||
if (h->client_addr)
|
||||
octstr_destroy(h->client_addr);
|
||||
|
||||
if (h->ua) octstr_destroy(h->ua);
|
||||
if (h->body) octstr_destroy(h->body);
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
- In content adaptation: Colour depth adjustment
|
||||
- logging a la access.log (one log per interface -- mm1-log, mm4-log, etc)
|
||||
- Need to parameterise some values: tmp dir, response messages (say on failed content adaptation)
|
||||
- Tests
|
||||
|
|
Loading…
Reference in New Issue