1
0
Fork 0

* Sends Error-sending-address-unresolved back to unresolved senders

* Adds detokenizing functionality
 * Adds a few example billing, resolver and detokenizer libraries
This commit is contained in:
shawarma 2005-03-11 20:29:10 +00:00
parent d51dc0d1fb
commit a695ea217f
11 changed files with 280 additions and 44 deletions

View File

@ -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':

View File

@ -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

View File

@ -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
};

View File

@ -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
};

View File

@ -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

View File

@ -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
};

View File

@ -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
};

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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