static void fixup_relayed_report(MmsMsg *m, MmscGrp *mmc, char *rtype, Octstr *status) { Octstr *value = mms_get_header_value(m, octstr_imm("Message-ID")); Octstr *newmsgid = NULL, *transid = NULL; /* Firstly, take care to look for the record we saved, and re-write the MessageID. */ if (value && mms_dlr_url_get(value, rtype, mmc->group_id, &newmsgid, &transid) == 0) { int x = octstr_search_char(newmsgid, ':', 0); if (x>=0) octstr_delete(newmsgid, 0, x+1); mms_replace_header_value(m, "Message-ID", octstr_get_cstr(newmsgid)); /* Add it back as original. */ mms_replace_header_value(m, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value)); #if 0 if (strcmp(rtype, "read-report") == 0 || (octstr_case_compare(status, octstr_imm("Deferred")) != 0 && octstr_case_compare(status, octstr_imm("Forwarded")) != 0)) mms_dlr_url_remove(value, rtype, mmc->group_id); /* only remove if not * interim status */ #endif } octstr_destroy(newmsgid); octstr_destroy(transid); octstr_destroy(value); }
static void kannel_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body) { /* Test on three cases: * 1. an smsbox reply of an remote kannel instance * 2. an smsc_http response (if used for MT to MO looping) * 3. an smsbox reply of partly successful sendings */ if ((status == HTTP_OK || status == HTTP_ACCEPTED) && (octstr_case_compare(body, octstr_imm("0: Accepted for delivery")) == 0 || octstr_case_compare(body, octstr_imm("Sent.")) == 0 || octstr_case_compare(body, octstr_imm("Ok.")) == 0 || octstr_ncompare(body, octstr_imm("Result: OK"),10) == 0)) { char id[UUID_STR_LEN + 1]; Octstr *mid; /* create Octstr from UUID */ uuid_unparse(msg->sms.id, id); mid = octstr_create(id); /* add to our own DLR storage */ if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) dlr_add(conn->id, mid, msg, 0); octstr_destroy(mid); bb_smscconn_sent(conn, msg, NULL); } else { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(body)); } }
/* * Append the User Data Header (UDH) including the length (UDHL). Only ports * UDH here - SAR UDH is added when (or if) we split the message. This is our * *specific* WDP layer. */ static void ota_pack_udh(Msg **msg, Octstr *doc_type) { (*msg)->sms.udhdata = octstr_create(""); if (octstr_case_compare(doc_type, octstr_imm("oma-settings")) == 0) octstr_append_from_hex((*msg)->sms.udhdata, "0605040B840B84"); else if (octstr_case_compare(doc_type, octstr_imm("syncsettings")) == 0) { octstr_append_from_hex((*msg)->sms.udhdata, "060504C34CC002"); } else octstr_append_from_hex((*msg)->sms.udhdata, "060504C34FC002"); }
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname) { Octstr *os; os = cfg_get(grp, varname); if (os == NULL) { *n = 0; return -1; } if (octstr_case_compare(os, octstr_imm("true")) == 0 || octstr_case_compare(os, octstr_imm("yes")) == 0 || octstr_case_compare(os, octstr_imm("on")) == 0 || octstr_case_compare(os, octstr_imm("1")) == 0) { *n = 1; } else if (octstr_case_compare(os, octstr_imm("false")) == 0 || octstr_case_compare(os, octstr_imm("no")) == 0 || octstr_case_compare(os, octstr_imm("off")) == 0 || octstr_case_compare(os, octstr_imm("0")) == 0) { *n = 0; } else { *n = 1; warning(0, "bool variable set to strange value, assuming 'true'"); } octstr_destroy(os); return 0; }
static void brunet_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body) { if (status == HTTP_OK || status == HTTP_ACCEPTED) { Dict *param; Octstr *status; if ((param = brunet_parse_body(body)) != NULL && (status = dict_get(param, octstr_imm("Status"))) != NULL && octstr_case_compare(status, octstr_imm("0")) == 0) { Octstr *msg_id; /* pass the MessageId for this MT to the logging facility */ if ((msg_id = dict_get(param, octstr_imm("MessageId"))) != NULL) msg->sms.binfo = octstr_duplicate(msg_id); bb_smscconn_sent(conn, msg, NULL); } else { error(0, "HTTP[%s]: Message was malformed. SMSC response `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(body)); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_duplicate(body)); } dict_destroy(param); } else { error(0, "HTTP[%s]: Message was rejected. SMSC reponse `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(body)); bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_REJECTED, octstr_duplicate(body)); } }
void wap_map_url(Octstr **osp, Octstr **send_msisdn_query, Octstr **send_msisdn_header, Octstr **send_msisdn_format, int *accept_cookies) { long i; Octstr *newurl, *tmp1, *tmp2; newurl = tmp1 = tmp2 = NULL; *send_msisdn_query = *send_msisdn_header = *send_msisdn_format = NULL; *accept_cookies = -1; debug("wsp",0,"WSP: Mapping url <%s>", octstr_get_cstr(*osp)); for (i = 0; url_map && i < gwlist_len(url_map); i++) { struct url_map_struct *entry; entry = gwlist_get(url_map, i); /* debug("wsp",0,"WSP: matching <%s> with <%s>", octstr_get_cstr(entry->url), octstr_get_cstr(entry->map_url)); */ /* DAVI: I only have '*' terminated entry->url implementation for now */ tmp1 = octstr_duplicate(entry->url); octstr_delete(tmp1, octstr_len(tmp1)-1, 1); /* remove last '*' */ tmp2 = octstr_copy(*osp, 0, octstr_len(tmp1)); debug("wsp",0,"WSP: Matching <%s> with <%s>", octstr_get_cstr(tmp1), octstr_get_cstr(tmp2)); if (octstr_case_compare(tmp2, tmp1) == 0) { /* rewrite url if configured to do so */ if (entry->map_url != NULL) { if (octstr_get_char(entry->map_url, octstr_len(entry->map_url)-1) == '*') { newurl = octstr_duplicate(entry->map_url); octstr_delete(newurl, octstr_len(newurl)-1, 1); octstr_append(newurl, octstr_copy(*osp, octstr_len(entry->url)-1, octstr_len(*osp)-octstr_len(entry->url)+1)); } else { newurl = octstr_duplicate(entry->map_url); } debug("wsp",0,"WSP: URL Rewriten from <%s> to <%s>", octstr_get_cstr(*osp), octstr_get_cstr(newurl)); octstr_destroy(*osp); *osp = newurl; } *accept_cookies = entry->accept_cookies; *send_msisdn_query = octstr_duplicate(entry->send_msisdn_query); *send_msisdn_header = octstr_duplicate(entry->send_msisdn_header); *send_msisdn_format = octstr_duplicate(entry->send_msisdn_format); octstr_destroy(tmp1); octstr_destroy(tmp2); break; } octstr_destroy(tmp1); octstr_destroy(tmp2); } }
static Octstr *get_dlr_notify_url(Octstr *msgid, char *report_type, Octstr *mmc_gid, Octstr *mmc_id, Octstr *status, Octstr **transid) { Octstr *xtransid = NULL, *url = NULL; mms_dlr_url_get(msgid, report_type, mmc_gid, &url, &xtransid); if (transid) *transid = xtransid; else octstr_destroy(xtransid); if (octstr_len(url) == 0) { if (url) mms_info(0, "MM7", NULL, "Sending delivery-report skipped: `url' is empty, `group_id'=[%s], `msgid'=[%s]", octstr_get_cstr(mmc_gid), octstr_get_cstr(msgid)); octstr_destroy(url); url = NULL; goto done; } else if (octstr_search(url, octstr_imm("msgid:"), 0) == 0) { /* a fake one, skip it. */ octstr_destroy(url); url = NULL; goto done; } #if 0 /* At what point do we delete it? For now, when we get a read report, * and also when we get a delivery report that is not 'deferred' or sent or forwarded */ if (strcmp(report_type, "read-report") == 0 || (octstr_case_compare(status, octstr_imm("Deferred")) != 0 && octstr_case_compare(status, octstr_imm("Forwarded")) != 0)) mms_dlr_url_remove(msgid, report_type, mmc_gid); #endif done: return url; }
/* Case-insensitive string lookup */ static long string_to_number(Octstr *ostr, struct table *table) { long i; gw_assert(initialized); for (i = 0; i < table->size; i++) { if (octstr_case_compare(ostr, table->strings[i]) == 0) { return table->linear ? i : table->numbers[i]; } } return -1; }
/* Case-insensitive string lookup according to passed WSP encoding version */ static long string_to_versioned_number(Octstr *ostr, struct table *table, int version) { long i, ret; gw_assert(initialized); /* walk the whole table and pick the highest versioned token */ ret = -1; for (i = 0; i < table->size; i++) { if (octstr_case_compare(ostr, table->strings[i]) == 0 && table->versions[i] <= version) { ret = table->linear ? i : table->numbers[i]; } } debug("wsp.strings",0,"WSP: Mapping `%s', WSP 1.%d to 0x%04lx.", octstr_get_cstr(ostr), version, ret); return ret; }
static void check_comparisons(void) { static const char *tab[] = { "", "a", "ab", "abc", "abcåäö", "ABCÅÄÖ", }; static const int n = sizeof(tab) / sizeof(tab[0]); int i, j; int sign_str, sign_oct; Octstr *os1, *os2; for (i = 0; i < n; ++i) { os1 = octstr_create(tab[i]); for (j = 0; j < n; ++j) { os2 = octstr_create(tab[j]); sign_str = signof(strcmp(tab[i], tab[j])); sign_oct = signof(octstr_compare(os1, os2)); if (sign_str != sign_oct) panic(0, "strcmp (%d) and octstr_compare (%d) differ for " "`%s' and `%s'", sign_str, sign_oct, tab[i], tab[j]); sign_str = signof(strcasecmp(tab[i], tab[j])); sign_oct = signof(octstr_case_compare(os1, os2)); if (sign_str != sign_oct) panic(0, "strcasecmp (%d) and octstr_case_compare (%d) " "differ for `%s' and `%s'", sign_str, sign_oct, tab[i], tab[j]); octstr_destroy(os2); } octstr_destroy(os1); } }
/* These functions are very similar to those in mmsproxy */ static int mm7soap_receive(MmsBoxHTTPClientInfo *h) { MSoapMsg_t *mreq = NULL, *mresp = NULL; int hstatus = HTTP_OK; List *rh = NULL; Octstr *reply_body = NULL; List *to = NULL; Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL, *uaprof = NULL; time_t expiryt = -1, delivert = -1, uaprof_tstamp = -1; MmsMsg *m = NULL; int status = 1000; unsigned char *msgtype = (unsigned char *)""; Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL; List *qhdr = http_create_empty_headers(); if (h->body) mreq = mm7_parse_soap(h->headers, h->body); if (mreq) msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq)); debug("mmsbox.mm7sendinterface", 0, " --> Enterred mm7dispatch interface, mreq=[%s] mtype=[%s] <-- ", mreq ? "Ok" : "Null", mreq ? (char *)msgtype : "Null"); if (!mreq) { mresp = mm7_make_resp(NULL, MM7_SOAP_FORMAT_CORRUPT, NULL,1); status = 4000; goto done; } mm7_get_envelope(mreq, &from, &to, &subject, &vasid, &expiryt, &delivert, &uaprof, &uaprof_tstamp); if (!from) from = octstr_create("anon@anon"); qdir = get_mmsbox_queue_dir(from, to, h->m, &mmc_id); /* get routing info. */ switch (mm7_msgtype(mreq)) { Octstr *value, *value2; case MM7_TAG_DeliverReq: m = mm7_soap_to_mmsmsg(mreq, from); if (m) { /* Store linked id so we use it in response. */ Octstr *linkedid = mm7_soap_header_value(mreq, octstr_imm("LinkedID")); List *qh = http_create_empty_headers(); int dlr; value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report")); if (value && octstr_case_compare(value, octstr_imm("Yes")) == 0) dlr = 1; else dlr = 0; if (delivert < 0) delivert = time(NULL); if (expiryt < 0) expiryt = time(NULL) + DEFAULT_EXPIRE; if (uaprof) { Octstr *sx = date_format_http(uaprof_tstamp); http_header_add(qh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof)); http_header_add(qh, "X-Mbuni-Timestamp", octstr_get_cstr(sx)); octstr_destroy(sx); } MOD_SUBJECT(m, h->m, from); qf = qfs->mms_queue_add(from, to, subject, h->m->id, mmc_id, delivert, expiryt, m, linkedid, NULL, NULL, NULL, NULL, qh, dlr, octstr_get_cstr(qdir), "MM7/SOAP-IN", NULL); if (qf == NULL) { status = 4000; mms_error(0, "MM7", h->m->id, "Failed to write queue entry for received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", octstr_get_cstr(h->m->id)); } else { msgid = mms_make_msgid(octstr_get_cstr(qf), NULL); mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); } octstr_destroy(linkedid); octstr_destroy(value); http_destroy_headers(qh); } else { mms_error(0, "MM7", h->m->id, "Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", octstr_get_cstr(h->m->id)); status = 4000; } mresp = mm7_make_resp(mreq, status, NULL,1); break; case MM7_TAG_DeliveryReportReq: value = mm7_soap_header_value(mreq, octstr_imm("MMStatus")); msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID")); if ((value2 = mm7_soap_header_value(mreq, octstr_imm("StatusText"))) != NULL) { http_header_add(qhdr, "X-Mbuni-StatusText", octstr_get_cstr(value2)); octstr_destroy(value2); value2 = NULL; } if ((value2 = mm7_soap_header_value(mreq, octstr_imm("Details"))) != NULL) { http_header_add(qhdr, "X-Mbuni-StatusDetails", octstr_get_cstr(value2)); octstr_destroy(value2); value2 = NULL; } m = mm7_soap_to_mmsmsg(mreq, from); value2 = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report", value, qhdr, uaprof, uaprof_tstamp, msgid); qf = qfs->mms_queue_add(from, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, value2, NULL, qhdr, 0, octstr_get_cstr(qdir), "MM7/SOAP-IN", NULL); if (qf) /* Log to access log */ mms_log("Received DLR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); else status = 4000; mresp = mm7_make_resp(mreq, status, NULL,1); octstr_destroy(value); octstr_destroy(value2); break; case MM7_TAG_ReadReplyReq: m = mm7_soap_to_mmsmsg(mreq, from); value = mm7_soap_header_value(mreq, octstr_imm("MMStatus")); msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID")); value2 = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, qhdr, uaprof, uaprof_tstamp, msgid); qf = qfs->mms_queue_add(from, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, value2, NULL, qhdr, 0, octstr_get_cstr(qdir), "MM7/SOAP-IN", NULL); if (qf) /* Log to access log */ mms_log("Received RR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); else status = 4000; mresp = mm7_make_resp(mreq, status, NULL,1); octstr_destroy(value); octstr_destroy(value2); break; default: mresp = mm7_make_resp(mreq, MM7_SOAP_UNSUPPORTED_OPERATION, NULL,1); status = MM7_SOAP_UNSUPPORTED_OPERATION; break; } done: if (mresp && mm7_soapmsg_to_httpmsg(mresp, &h->m->ver, &rh, &reply_body) == 0) http_send_reply(h->client, hstatus, rh, reply_body); else http_close_client(h->client); debug("mmsbox.mm7sendinterface", 0, " --> leaving mm7dispatch interface, mresp=[%s], body=[%s], mm7_status=[%d] <-- ", mresp ? "ok" : "(null)", reply_body ? "ok" : "(null)", status); octstr_destroy(from); octstr_destroy(subject); octstr_destroy(vasid); octstr_destroy(msgid); octstr_destroy(qf); octstr_destroy(uaprof); mms_destroy(m); http_destroy_headers(rh); octstr_destroy(reply_body); mm7_soap_destroy(mresp); mm7_soap_destroy(mreq); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(mmc_id); http_destroy_headers(qhdr); return MM7_SOAP_STATUS_OK(status) ? 0 : -1; }
static Cfg *init_bearerbox(Cfg *cfg) { CfgGroup *grp; Octstr *log, *val; long loglevel, store_dump_freq, value; int lf, m; #ifdef HAVE_LIBSSL Octstr *ssl_server_cert_file; Octstr *ssl_server_key_file; int ssl_enabled = 0; #endif /* HAVE_LIBSSL */ Octstr *http_proxy_host = NULL; long http_proxy_port = -1; int http_proxy_ssl = 0; List *http_proxy_exceptions = NULL; Octstr *http_proxy_username = NULL; Octstr *http_proxy_password = NULL; Octstr *http_proxy_exceptions_regex = NULL; /* defaults: use localtime and markers for access-log */ lf = m = 1; grp = cfg_get_single_group(cfg, octstr_imm("core")); log = cfg_get(grp, octstr_imm("log-file")); if (log != NULL) { if (cfg_get_integer(&loglevel, grp, octstr_imm("log-level")) == -1) loglevel = 0; log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL); octstr_destroy(log); } if ((val = cfg_get(grp, octstr_imm("syslog-level"))) != NULL) { long level; Octstr *facility; if ((facility = cfg_get(grp, octstr_imm("syslog-facility"))) != NULL) { log_set_syslog_facility(octstr_get_cstr(facility)); octstr_destroy(facility); } if (octstr_compare(val, octstr_imm("none")) == 0) { log_set_syslog(NULL, 0); } else if (octstr_parse_long(&level, val, 0, 10) > 0) { log_set_syslog("bearerbox", level); } octstr_destroy(val); } else { log_set_syslog(NULL, 0); } if (check_config(cfg) == -1) panic(0, "Cannot start with corrupted configuration"); /* determine which timezone we use for access logging */ if ((log = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) { lf = (octstr_case_compare(log, octstr_imm("gmt")) == 0) ? 0 : 1; octstr_destroy(log); } /* should predefined markers be used, ie. prefixing timestamp */ cfg_get_bool(&m, grp, octstr_imm("access-log-clean")); /* custom access-log format */ if ((log = cfg_get(grp, octstr_imm("access-log-format"))) != NULL) { bb_alog_init(log); octstr_destroy(log); } /* open access-log file */ if ((log = cfg_get(grp, octstr_imm("access-log"))) != NULL) { alog_open(octstr_get_cstr(log), lf, m ? 0 : 1); octstr_destroy(log); } if (cfg_get_integer(&store_dump_freq, grp, octstr_imm("store-dump-freq")) == -1) store_dump_freq = -1; log = cfg_get(grp, octstr_imm("store-file")); /* initialize the store file */ if (log != NULL) { warning(0, "'store-file' option deprecated, please use 'store-location' and 'store-type' instead."); val = octstr_create("file"); } else { log = cfg_get(grp, octstr_imm("store-location")); val = cfg_get(grp, octstr_imm("store-type")); } if (store_init(val, log, store_dump_freq, msg_pack, msg_unpack_wrapper) == -1) panic(0, "Could not start with store init failed."); octstr_destroy(val); octstr_destroy(log); cfg_get_integer(&http_proxy_port, grp, octstr_imm("http-proxy-port")); #ifdef HAVE_LIBSSL cfg_get_bool(&http_proxy_ssl, grp, octstr_imm("http-proxy-ssl")); #endif /* HAVE_LIBSSL */ http_proxy_host = cfg_get(grp, octstr_imm("http-proxy-host")); http_proxy_username = cfg_get(grp, octstr_imm("http-proxy-username")); http_proxy_password = cfg_get(grp, octstr_imm("http-proxy-password")); http_proxy_exceptions = cfg_get_list(grp, octstr_imm("http-proxy-exceptions")); http_proxy_exceptions_regex = cfg_get(grp, octstr_imm("http-proxy-exceptions-regex")); conn_config_ssl (grp); /* * Make sure we have "ssl-server-cert-file" and "ssl-server-key-file" specified * in the core group since we need it to run SSL-enabled internal box * connections configured via "smsbox-port-ssl = yes" and "wapbox-port-ssl = yes". * Check only these, because for "admin-port-ssl" and "sendsms-port-ssl" for the * SSL-enabled HTTP servers are probed within gw/bb_http.c:httpadmin_start() */ #ifdef HAVE_LIBSSL ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file")); ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file")); if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) { /* we are fine, at least files are specified in the configuration */ } else { cfg_get_bool(&ssl_enabled, grp, octstr_imm("smsbox-port-ssl")); cfg_get_bool(&ssl_enabled, grp, octstr_imm("wapbox-port-ssl")); if (ssl_enabled) { panic(0, "You MUST specify cert and key files within core group for SSL-enabled inter-box connections!"); } } octstr_destroy(ssl_server_cert_file); octstr_destroy(ssl_server_key_file); #endif /* HAVE_LIBSSL */ /* if all seems to be OK by the first glimpse, real start-up */ outgoing_sms = gwlist_create(); incoming_sms = gwlist_create(); outgoing_wdp = gwlist_create(); incoming_wdp = gwlist_create(); outgoing_sms_counter = counter_create(); incoming_sms_counter = counter_create(); incoming_dlr_counter = counter_create(); outgoing_dlr_counter = counter_create(); outgoing_wdp_counter = counter_create(); incoming_wdp_counter = counter_create(); status_mutex = mutex_create(); outgoing_sms_load = load_create(); /* add 60,300,-1 entries */ load_add_interval(outgoing_sms_load, 60); load_add_interval(outgoing_sms_load, 300); load_add_interval(outgoing_sms_load, -1); incoming_sms_load = load_create(); /* add 60,300,-1 entries */ load_add_interval(incoming_sms_load, 60); load_add_interval(incoming_sms_load, 300); load_add_interval(incoming_sms_load, -1); incoming_dlr_load = load_create(); /* add 60,300,-1 entries to dlr */ load_add_interval(incoming_dlr_load, 60); load_add_interval(incoming_dlr_load, 300); load_add_interval(incoming_dlr_load, -1); outgoing_dlr_load = load_create(); /* add 60,300,-1 entries to dlr */ load_add_interval(outgoing_dlr_load, 60); load_add_interval(outgoing_dlr_load, 300); load_add_interval(outgoing_dlr_load, -1); setup_signal_handlers(); /* http-admin is REQUIRED */ httpadmin_start(cfg); if (cfg_get_integer(&max_incoming_sms_qlength, grp, octstr_imm("maximum-queue-length")) == -1) max_incoming_sms_qlength = -1; else { warning(0, "Option 'maximum-queue-length' is deprecated! Please use" " 'sms-incoming-queue-limit' instead!"); } if (max_incoming_sms_qlength == -1 && cfg_get_integer(&max_incoming_sms_qlength, grp, octstr_imm("sms-incoming-queue-limit")) == -1) max_incoming_sms_qlength = -1; if (cfg_get_integer(&max_outgoing_sms_qlength, grp, octstr_imm("sms-outgoing-queue-limit")) == -1) max_outgoing_sms_qlength = -1; if (max_outgoing_sms_qlength < 0) max_outgoing_sms_qlength = DEFAULT_OUTGOING_SMS_QLENGTH; if (cfg_get_integer(&value, grp, octstr_imm("http-timeout")) == 0) http_set_client_timeout(value); #ifndef NO_SMS { List *list; list = cfg_get_multi_group(cfg, octstr_imm("smsc")); if (list != NULL) { gwlist_destroy(list, NULL); if (start_smsc(cfg) == -1) { panic(0, "Unable to start SMSCs."); return NULL; } } } #endif #ifndef NO_WAP grp = cfg_get_single_group(cfg, octstr_imm("core")); val = cfg_get(grp, octstr_imm("wdp-interface-name")); if (val != NULL && octstr_len(val) > 0) start_udp(cfg); octstr_destroy(val); if (cfg_get_single_group(cfg, octstr_imm("wapbox")) != NULL) start_wap(cfg); #endif if (http_proxy_host != NULL && http_proxy_port > 0) { http_use_proxy(http_proxy_host, http_proxy_port, http_proxy_ssl, http_proxy_exceptions, http_proxy_username, http_proxy_password, http_proxy_exceptions_regex); } octstr_destroy(http_proxy_host); octstr_destroy(http_proxy_username); octstr_destroy(http_proxy_password); octstr_destroy(http_proxy_exceptions_regex); gwlist_destroy(http_proxy_exceptions, octstr_destroy_item); return cfg; }
static Cfg *init_bearerbox(Cfg *cfg) { CfgGroup *grp; Octstr *log, *val; long loglevel; int lf, m; #ifdef HAVE_LIBSSL Octstr *ssl_server_cert_file; Octstr *ssl_server_key_file; int ssl_enabled = 0; #endif /* HAVE_LIBSSL */ /* defaults: use localtime and markers for access-log */ lf = m = 1; grp = cfg_get_single_group(cfg, octstr_imm("core")); log = cfg_get(grp, octstr_imm("log-file")); if (log != NULL) { if (cfg_get_integer(&loglevel, grp, octstr_imm("log-level")) == -1) loglevel = 0; log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL); octstr_destroy(log); } if (check_config(cfg) == -1) panic(0, "Cannot start with corrupted configuration"); /* determine which timezone we use for access logging */ if ((log = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) { lf = (octstr_case_compare(log, octstr_imm("gmt")) == 0) ? 0 : 1; octstr_destroy(log); } /* should predefined markers be used, ie. prefixing timestamp */ cfg_get_bool(&m, grp, octstr_imm("access-log-clean")); /* custom access-log format */ if ((log = cfg_get(grp, octstr_imm("access-log-format"))) != NULL) { bb_alog_init(log); octstr_destroy(log); } /* open access-log file */ if ((log = cfg_get(grp, octstr_imm("access-log"))) != NULL) { alog_open(octstr_get_cstr(log), lf, m ? 0 : 1); octstr_destroy(log); } log = cfg_get(grp, octstr_imm("store-file")); /* initialize the store file */ if (log != NULL) { store_init(log); octstr_destroy(log); } conn_config_ssl (grp); /* * Make sure we have "ssl-server-cert-file" and "ssl-server-key-file" specified * in the core group since we need it to run SSL-enabled internal box * connections configured via "smsbox-port-ssl = yes" and "wapbox-port-ssl = yes". * Check only these, because for "admin-port-ssl" and "sendsms-port-ssl" for the * SSL-enabled HTTP servers are probed within gw/bb_http.c:httpadmin_start() */ #ifdef HAVE_LIBSSL ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file")); ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file")); if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) { /* we are fine, at least files are specified in the configuration */ } else { cfg_get_bool(&ssl_enabled, grp, octstr_imm("smsbox-port-ssl")); cfg_get_bool(&ssl_enabled, grp, octstr_imm("wapbox-port-ssl")); if (ssl_enabled) { panic(0, "You MUST specify cert and key files within core group for SSL-enabled inter-box connections!"); } } octstr_destroy(ssl_server_cert_file); octstr_destroy(ssl_server_key_file); #endif /* HAVE_LIBSSL */ /* if all seems to be OK by the first glimpse, real start-up */ outgoing_sms = list_create(); incoming_sms = list_create(); outgoing_wdp = list_create(); incoming_wdp = list_create(); outgoing_sms_counter = counter_create(); incoming_sms_counter = counter_create(); outgoing_wdp_counter = counter_create(); incoming_wdp_counter = counter_create(); status_mutex = mutex_create(); setup_signal_handlers(); /* http-admin is REQUIRED */ httpadmin_start(cfg); if (cfg_get_integer(&max_incoming_sms_qlength, grp, octstr_imm("maximum-queue-length")) == -1) max_incoming_sms_qlength = -1; else { warning(0, "Option 'maximum-queue-length' is deprecated! Please use" " 'sms-incoming-queue-limit' instead!"); } if (max_incoming_sms_qlength == -1 && cfg_get_integer(&max_incoming_sms_qlength, grp, octstr_imm("sms-incoming-queue-limit")) == -1) max_incoming_sms_qlength = -1; #ifndef NO_SMS { List *list; list = cfg_get_multi_group(cfg, octstr_imm("smsc")); if (list != NULL) { start_smsc(cfg); list_destroy(list, NULL); } } #endif #ifndef NO_WAP grp = cfg_get_single_group(cfg, octstr_imm("core")); val = cfg_get(grp, octstr_imm("wdp-interface-name")); if (val != NULL && octstr_len(val) > 0) start_udp(cfg); octstr_destroy(val); if (cfg_get_single_group(cfg, octstr_imm("wapbox")) != NULL) start_wap(cfg); #endif return cfg; }
static int mm7http_receive(MmsBoxHTTPClientInfo *h) { MmsMsg *m = NULL; List *mh = NULL; int hstatus = HTTP_OK; List *rh = http_create_empty_headers(); Octstr *reply_body = NULL; List *to = NULL; Octstr *hto = NULL, *subject = NULL, *msgid = NULL; Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL; time_t expiryt = -1, deliveryt = -1; Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *s; int msize; int dlr, rr; int mtype; List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers(); parse_cgivars(h->headers, h->body, &h->cgivars, &cgivars_ctypes); hfrom = http_cgi_variable(h->cgivars, "from"); hto = http_cgi_variable(h->cgivars, "to"); body = http_cgi_variable(h->cgivars, "mms"); msize = octstr_len(body); debug("mmsbox.mm7http.sendinterface", 0, " --> Enterred http-mmsc send interface, blen=[%d] <--- ", msize); if (hto == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Missing 'to' argument"); goto done; } else if (hfrom == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Missing 'from' argument"); goto done; } else if (body == NULL || /* A message is required, and must parse */ (m = mms_frombinary(body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Unexpected MMS message, no content?"); goto done; } to = octstr_split_words(hto); mtype = mms_messagetype(m); mh = mms_message_headers(m); /* find interesting headers. */ subject = http_header_value(mh, octstr_imm("Subject")); /* Find expiry and delivery times */ if ((s = http_header_value(mh, octstr_imm("X-Mms-Expiry"))) != NULL) { expiryt = date_parse_http(s); octstr_destroy(s); } else expiryt = time(NULL) + DEFAULT_EXPIRE; if ((s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time"))) != NULL) { deliveryt = date_parse_http(s); octstr_destroy(s); } else deliveryt = 0; qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */ switch(mtype) { Octstr *value, *value2; case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_RETRIEVE_CONF: /* Get/make a Message ID */ if ((msgid = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL) { /* Make a message id for it directly. We need it below. */ msgid = mms_make_msgid(NULL, NULL); mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); } if ((value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"))) != NULL && octstr_case_compare(value, octstr_imm("Yes")) == 0) dlr = 1; else dlr = 0; octstr_destroy(value); if ((value = http_header_value(mh, octstr_imm("X-Mms-Read-Report"))) != NULL && octstr_case_compare(value, octstr_imm("Yes")) == 0) rr = 1; else rr = 0; octstr_destroy(value); if (deliveryt < 0) deliveryt = time(NULL); if (expiryt < 0) expiryt = time(NULL) + DEFAULT_EXPIRE; 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"); MOD_SUBJECT(m, h->m, hfrom); if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it * if a DLR is relayed backwards. */ Octstr *t = mms_maketransid(NULL, octstr_imm(MM_NAME)); /* make a fake transaction id so dlr works*/ http_header_add(rqh, "X-Mbuni-TransactionID", octstr_get_cstr(t)); if (dlr) dlr_uri = octstr_format("msgid:%S", msgid); if (rr) rr_uri = octstr_format("msgid:%S", msgid); octstr_destroy(t); } /* Save it, put message id in header, return. */ qf = qfs->mms_queue_add(hfrom, to, subject, h->m->id, mmc_id, deliveryt, expiryt, m, NULL, NULL, NULL, dlr_uri, rr_uri, rqh, dlr, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_OK; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; break; case MMS_MSGTYPE_DELIVERY_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report", value, rqh, NULL, 0, msgid); if (mmc_id == NULL && value2) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("DeliveryReport", hfrom, to, -1, msgid,value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_OK; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_READ_ORIG_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, rqh, NULL, 0, msgid); if (mmc_id == NULL && value2) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; } done: http_header_add(rh, "X-Mbuni-Version", VERSION); http_send_reply(h->client, hstatus, rh, msgid ? msgid : (qf ? qf : octstr_imm(""))); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(subject); octstr_destroy(qf); octstr_destroy(mmc_id); octstr_destroy(msgid); http_destroy_headers(mh); http_destroy_headers(rh); http_destroy_headers(rqh); if (m) mms_destroy(m); http_destroy_cgiargs(cgivars_ctypes); return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; }
int main(int argc, char **argv) { DBPool *pool; DBConf *conf = NULL; /* for compiler please */ unsigned int num_threads = 1; unsigned long i; int opt; time_t start = 0, end = 0; double run_time; Octstr *user, *pass, *db, *host, *db_type; int j, bail_out; user = pass = db = host = db_type = NULL; gwlib_init(); sql = octstr_imm("SHOW STATUS"); while ((opt = getopt(argc, argv, "v:h:u:p:d:s:q:t:S:T:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'h': host = octstr_create(optarg); break; case 'u': user = octstr_create(optarg); break; case 'p': pass = octstr_create(optarg); break; case 'd': db = octstr_create(optarg); break; case 'S': octstr_destroy(sql); sql = octstr_create(optarg); break; case 's': pool_size = atoi(optarg); break; case 'q': queries = atoi(optarg); break; case 't': num_threads = atoi(optarg); break; case 'T': db_type = octstr_create(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (!optind) { help(); exit(0); } if (!db_type) { info(0, "No database type given assuming MySQL."); } else if (octstr_case_compare(db_type, octstr_imm("mysql")) == 0) { info(0, "Do tests for mysql database."); database_type = DBPOOL_MYSQL; } else if (octstr_case_compare(db_type, octstr_imm("oracle")) == 0) { info(0, "Do tests for oracle database."); database_type = DBPOOL_ORACLE; } else if (octstr_case_compare(db_type, octstr_imm("sqlite")) == 0) { info(0, "Do tests for sqlite database."); database_type = DBPOOL_SQLITE; } else if (octstr_case_compare(db_type, octstr_imm("sqlite3")) == 0) { info(0, "Do tests for sqlite3 database."); database_type = DBPOOL_SQLITE3; } else { panic(0, "Unknown database type '%s'", octstr_get_cstr(db_type)); } /* check if we have the database connection details */ switch (database_type) { case DBPOOL_ORACLE: bail_out = (!user || !pass || !db) ? 1 : 0; break; case DBPOOL_SQLITE: case DBPOOL_SQLITE3: bail_out = (!db) ? 1 : 0; break; default: bail_out = (!host || !user || !pass || !db) ? 1 : 0; break; } if (bail_out) { help(); panic(0, "Database connection details are not fully provided!"); } for (j = 0; j < 1; j++) { /* create DBConf */ switch (database_type) { #ifdef HAVE_MYSQL case DBPOOL_MYSQL: conf = mysql_create_conf(user,pass,db,host); client_thread = mysql_client_thread; break; #endif #ifdef HAVE_ORACLE case DBPOOL_ORACLE: conf = oracle_create_conf(user, pass, db); client_thread = oracle_client_thread; break; #endif #ifdef HAVE_SQLITE case DBPOOL_SQLITE: conf = sqlite_create_conf(db); client_thread = sqlite_client_thread; break; #endif #ifdef HAVE_SQLITE3 case DBPOOL_SQLITE3: conf = sqlite3_create_conf(db); client_thread = sqlite3_client_thread; break; #endif default: panic(0, "ooops ...."); }; /* create */ info(0,"Creating database pool to `%s' with %d connections type '%s'.", (host ? octstr_get_cstr(host) : octstr_get_cstr(db)), pool_size, octstr_get_cstr(db_type)); pool = dbpool_create(database_type, conf, pool_size); debug("",0,"Connections within pool: %ld", dbpool_conn_count(pool)); for (i = 0; i < num_threads; ++i) { if (gwthread_create(inc_dec_thread, pool) == -1) panic(0, "Could not create thread %ld", i); } gwthread_join_all(); info(0, "Connections within pool: %ld", dbpool_conn_count(pool)); info(0, "Checked pool, %d connections still active and ok", dbpool_check(pool)); /* queries */ info(0,"SQL query is `%s'", octstr_get_cstr(sql)); time(&start); for (i = 0; i < num_threads; ++i) { #if 0 if (gwthread_create(inc_dec_thread, pool) == -1) panic(0, "Couldnot create thread %ld", i); #endif if (gwthread_create(client_thread, pool) == -1) panic(0, "Couldnot create thread %ld", i); } gwthread_join_all(); time(&end); run_time = difftime(end, start); info(0, "%ld requests in %.2f seconds, %.2f requests/s.", (queries * num_threads), run_time, (float) (queries * num_threads) / (run_time==0?1:run_time)); /* check all active connections */ debug("",0,"Connections within pool: %ld", dbpool_conn_count(pool)); info(0,"Checked pool, %d connections still active and ok", dbpool_check(pool)); info(0,"Destroying pool"); dbpool_destroy(pool); } /* for loop */ octstr_destroy(sql); octstr_destroy(db_type); octstr_destroy(user); octstr_destroy(pass); octstr_destroy(db); octstr_destroy(host); gwlib_shutdown(); return 0; }
int smsc_http_create(SMSCConn *conn, CfgGroup *cfg) { ConnData *conndata = NULL; Octstr *type; int ssl = 0; /* indicate if SSL-enabled server should be used */ long max_ps; if ((type = cfg_get(cfg, octstr_imm("system-type"))) == NULL) { error(0, "HTTP[%s]: 'system-type' missing in smsc 'http' record.", octstr_get_cstr(conn->id)); octstr_destroy(type); return -1; } conndata = gw_malloc(sizeof(ConnData)); /* reset conndata */ memset(conndata, 0, sizeof(ConnData)); conn->data = conndata; conndata->http_ref = NULL; conndata->data = NULL; if (cfg_get_integer(&conndata->port, cfg, octstr_imm("port")) == -1) { warning(0, "HTTP[%s]: 'port' not set in smsc 'http' group.", octstr_get_cstr(conn->id)); conndata->port = -1; } conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip")); conndata->send_url = cfg_get(cfg, octstr_imm("send-url")); conndata->username = cfg_get(cfg, octstr_imm("smsc-username")); conndata->password = cfg_get(cfg, octstr_imm("smsc-password")); conndata->system_id = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender")); cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding")); cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep")); conndata->proxy = cfg_get(cfg, octstr_imm("system-id")); cfg_get_bool(&ssl, cfg, octstr_imm("use-ssl")); conndata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url")); conndata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset")); if (cfg_get_integer(&max_ps, cfg, octstr_imm("max-pending-submits")) == -1 || max_ps < 1) max_ps = 10; conndata->max_pending_sends = semaphore_create(max_ps); if (conndata->port <= 0 && conndata->send_url == NULL) { error(0, "Sender and receiver disabled. Dummy SMSC not allowed."); goto error; } if (conndata->send_url == NULL) panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.", octstr_get_cstr(conn->id)); if (octstr_case_compare(type, octstr_imm("kannel")) == 0) { if (conndata->username == NULL || conndata->password == NULL) { error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc", octstr_get_cstr(conn->id)); goto error; } conndata->callbacks = &smsc_http_kannel_callback; } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) { conndata->callbacks = &smsc_http_brunet_callback; } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) { conndata->callbacks = &smsc_http_xidris_callback; } else if (octstr_case_compare(type, octstr_imm("generic")) == 0) { conndata->callbacks = &smsc_http_generic_callback; } else if (octstr_case_compare(type, octstr_imm("clickatell")) == 0) { conndata->callbacks = &smsc_http_clickatell_callback; } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) { conndata->callbacks = &smsc_http_wapme_callback; } /* * ADD NEW HTTP SMSC TYPES HERE */ else { error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } if (conndata->callbacks != NULL && conndata->callbacks->init != NULL && conndata->callbacks->init(conn, cfg)) { error(0, "HTTP[%s]: submodule '%s' init failed.", octstr_get_cstr(conn->id), octstr_get_cstr(type)); goto error; } conndata->open_sends = counter_create(); conndata->msg_to_send = gwlist_create(); gwlist_add_producer(conndata->msg_to_send); conndata->http_ref = http_caller_create(); conn->name = octstr_format("HTTP%s:%S:%d", (ssl?"S":""), type, conndata->port); if (conndata->send_url != NULL) { conn->status = SMSCCONN_ACTIVE; } else { conn->status = SMSCCONN_ACTIVE_RECV; } conn->connect_time = time(NULL); conn->shutdown = httpsmsc_shutdown; conn->queued = httpsmsc_queued; conn->send_msg = httpsmsc_send; conndata->shutdown = 0; /* start receiver thread */ if (conndata->port > 0) { if (http_open_port(conndata->port, ssl) == -1) goto error; if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1) goto error; } else conndata->receive_thread = -1; /* start sender threads */ if (conndata->send_url) { if ((conndata->send_cb_thread = gwthread_create(httpsmsc_send_cb, conn)) == -1) goto error; if ((conndata->sender_thread = gwthread_create(httpsmsc_sender, conn)) == -1) goto error; } else { conndata->send_cb_thread = conndata->sender_thread = -1; } info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id)); octstr_destroy(type); return 0; error: error(0, "HTTP[%s]: Failed to create HTTP SMSC connection", octstr_get_cstr(conn->id)); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT; conn->status = SMSCCONN_DEAD; octstr_destroy(type); return -1; }
mCfg *mms_cfg_read(Octstr *file) { Octstr *sf; List *lines; int i, n; mCfg *cfg; mCfgGrp *grp = NULL; int skip = 0; gw_assert(file); if ((sf = octstr_read_file(octstr_get_cstr(file))) == NULL) { error(errno, "failed to read config from `%s'", octstr_get_cstr(file)); return NULL; } cfg = gw_malloc(sizeof *cfg); cfg->file = octstr_duplicate(file); cfg->grps = dict_create(7, NULL); lines = octstr_split(sf, octstr_imm("\n")); for (i = 0, n = gwlist_len(lines); i < n; i++) { Octstr *current = gwlist_get(lines,i); int pos; octstr_strip_blanks(current); if (octstr_len(current) == 0) { /* end of group. */ grp = NULL; skip = 0; continue; } else if (skip || octstr_get_char(current, 0) == '#') continue; if ((pos = octstr_search_char(current, '=',0)) > 0) { /* a field name. first see if start of grp */ Octstr *field = octstr_copy(current,0,pos); Octstr *value = octstr_copy(current,pos+1,octstr_len(current)); octstr_strip_blanks(field); fixup_value(value, i+1); #if 0 info(0, "field/value: [%s - %s]", octstr_get_cstr(field), octstr_get_cstr(value)); #endif if (octstr_case_compare(field, octstr_imm("group")) == 0) if (grp == NULL) { /* grp name. */ int ismulti = is_multigroup(value); if (ismulti < 0) { info(0, "Skipping unknown group `%s' at line %d of conf file", octstr_get_cstr(value), i+1); skip = 1; } else { grp = gw_malloc(sizeof *grp); grp->name = octstr_duplicate(value); grp->fields = dict_create(23, (void (*)(void *))octstr_destroy); if (ismulti) { List *l = dict_get(cfg->grps, value); if (l == NULL) { l = gwlist_create(); dict_put(cfg->grps, value, l); } gwlist_append(l, grp); } else if (dict_put_once(cfg->grps, value, grp) == 0) panic(0, "Group `%s' [at line %d] cannot appear more " "than once in config!", octstr_get_cstr(value), i+1); } } else panic(0,"`group' is an illegal field name " "within a group at line %d in config file!", i+1); else if (grp) /* an ordinary field name. */ check_and_add_field(grp, field, value,i+1); else panic(0, "A group must begin with a `group = group_name' " "clause [at line %d in config file]", i+1); octstr_destroy(field); octstr_destroy(value); } else panic(0, "mal-formed entry in conf file at line %d!", i+1); } gwlist_destroy(lines, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(sf); return cfg; }
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, char *vasid, List *hdrs, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL, *resp = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh = http_create_empty_headers(), *ph = NULL; Octstr *body = NULL, *rbody = NULL, *xver = NULL; char *msgtype; mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); http_header_remove_all(rh, "X-Mms-Allow-Adaptations"); http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to)); http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from)); xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); octstr_destroy(xver); if (mtype == MMS_MSGTYPE_SEND_REQ || mtype == MMS_MSGTYPE_RETRIEVE_CONF) { msgtype = "MultiMediaMessage"; mms_make_sendreq(m); /* ensure it is a sendreq. */ } else if (mtype == MMS_MSGTYPE_DELIVERY_IND) msgtype = "DeliveryReport"; else msgtype = "ReadReply"; http_header_add(rh, "X-NOKIA-MMSC-Message-Type", msgtype); if (hdrs) http_header_combine(rh, hdrs); /* If specified, then update and pass on. */ http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message"); /* Patch the message FROM and TO fields. */ mms_replace_header_value(m, "From", octstr_get_cstr(from)); mms_replace_header_value(m, "To", octstr_get_cstr(to)); mms_replace_header_value(m,"X-Mms-Transaction-ID", transid ? octstr_get_cstr(transid) : "000"); body = mms_tobinary(m); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { MmsMsg *mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL; resp = octstr_imm("Ok"); if (mresp && mms_messagetype(mresp) == MMS_MSGTYPE_SEND_CONF) resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status")); if (octstr_case_compare(resp, octstr_imm("ok")) != 0) hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */ else if (mresp) ret = mms_get_header_value(mresp, octstr_imm("Message-ID")); mms_destroy(mresp); } if (hstatus < 0) ret = NULL; else { hstatus = http_status_class(hstatus); if (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus == HTTP_STATUS_CLIENT_ERROR) ret = NULL; else if (!ret) ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id")); } *retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); #if 0 mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]", octstr_get_cstr(mmc->id), hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)"); #endif http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(resp); return ret; }
static Cfg *init_wapbox(Cfg *cfg) { CfgGroup *grp; Octstr *s; Octstr *logfile; int lf, m; long value; lf = m = 1; cfg_dump(cfg); /* * Extract info from the core group. */ grp = cfg_get_single_group(cfg, octstr_imm("core")); if (grp == NULL) panic(0, "No 'core' group in configuration."); if (cfg_get_integer(&bearerbox_port,grp,octstr_imm("wapbox-port")) == -1) panic(0, "No 'wapbox-port' in core group"); #ifdef HAVE_LIBSSL cfg_get_bool(&bearerbox_ssl, grp, octstr_imm("wapbox-port-ssl")); #endif /* HAVE_LIBSSL */ /* load parameters that could be later reloaded */ config_reload(0); conn_config_ssl(grp); /* * And the rest of the pull info comes from the wapbox group. */ grp = cfg_get_single_group(cfg, octstr_imm("wapbox")); if (grp == NULL) panic(0, "No 'wapbox' group in configuration."); bearerbox_host = cfg_get(grp, octstr_imm("bearerbox-host")); if (cfg_get_integer(&timer_freq, grp, octstr_imm("timer-freq")) == -1) timer_freq = DEFAULT_TIMER_FREQ; logfile = cfg_get(grp, octstr_imm("log-file")); if (logfile != NULL) { log_open(octstr_get_cstr(logfile), logfilelevel, GW_NON_EXCL); info(0, "Starting to log to file %s level %ld", octstr_get_cstr(logfile), logfilelevel); } octstr_destroy(logfile); if ((s = cfg_get(grp, octstr_imm("syslog-level"))) != NULL) { long level; Octstr *facility; if ((facility = cfg_get(grp, octstr_imm("syslog-facility"))) != NULL) { log_set_syslog_facility(octstr_get_cstr(facility)); octstr_destroy(facility); } if (octstr_compare(s, octstr_imm("none")) == 0) { log_set_syslog(NULL, 0); debug("wap", 0, "syslog parameter is none"); } else if (octstr_parse_long(&level, s, 0, 10) > 0) { log_set_syslog("wapbox", level); debug("wap", 0, "syslog parameter is %ld", level); } octstr_destroy(s); } else { log_set_syslog(NULL, 0); debug("wap", 0, "no syslog parameter"); } /* determine which timezone we use for access logging */ if ((s = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) { lf = (octstr_case_compare(s, octstr_imm("gmt")) == 0) ? 0 : 1; octstr_destroy(s); } /* should predefined markers be used, ie. prefixing timestamp */ cfg_get_bool(&m, grp, octstr_imm("access-log-clean")); /* open access-log file */ if ((s = cfg_get(grp, octstr_imm("access-log"))) != NULL) { info(0, "Logging accesses to '%s'.", octstr_get_cstr(s)); alog_open(octstr_get_cstr(s), lf, m ? 0 : 1); octstr_destroy(s); } if (cfg_get_integer(&value, grp, octstr_imm("http-timeout")) == 0) http_set_client_timeout(value); /* configure the 'wtls' group */ #if (HAVE_WTLS_OPENSSL) /* Load up the necessary keys */ grp = cfg_get_single_group(cfg, octstr_imm("wtls")); if (grp != NULL) { if ((s = cfg_get(grp, octstr_imm("certificate-file"))) != NULL) { if (octstr_compare(s, octstr_imm("none")) == 0) { debug("bbox", 0, "certificate file not set"); } else { /* Load the certificate into the necessary parameter */ get_cert_from_file(s, &x509_cert); gw_assert(x509_cert != NULL); debug("bbox", 0, "certificate parameter is %s", octstr_get_cstr(s)); } octstr_destroy(s); } else panic(0, "No 'certificate-file' in wtls group"); if ((s = cfg_get(grp, octstr_imm("privatekey-file"))) != NULL) { Octstr *password; password = cfg_get(grp, octstr_imm("privatekey-password")); if (octstr_compare(s, octstr_imm("none")) == 0) { debug("bbox", 0, "privatekey-file not set"); } else { /* Load the private key into the necessary parameter */ get_privkey_from_file(s, &private_key, password); gw_assert(private_key != NULL); debug("bbox", 0, "certificate parameter is %s", octstr_get_cstr(s)); } if (password != NULL) octstr_destroy(password); octstr_destroy(s); } else panic(0, "No 'privatekey-file' in wtls group"); } #endif /* * Check if we have a 'radius-acct' proxy group and start the * corresponding thread for the proxy. */ grp = cfg_get_single_group(cfg, octstr_imm("radius-acct")); if (grp) { radius_acct_init(grp); } /* * We pass ppg configuration groups to the ppg module. */ grp = cfg_get_single_group(cfg, octstr_imm("ppg")); if (grp == NULL) { cfg_destroy(cfg); return NULL; } return cfg; }
static int mm7eaif_receive(MmsBoxHTTPClientInfo *h) { MmsMsg *m = NULL; List *mh = NULL; int hstatus = HTTP_NO_CONTENT; List *rh = http_create_empty_headers(); List *rqh = http_create_empty_headers(); Octstr *reply_body = NULL, *value = NULL, *value2 = NULL; List *to = gwlist_create(), *hto = NULL; Octstr *subject = NULL, *otransid = NULL, *msgid = NULL; Octstr *hfrom = NULL, *rr_uri = NULL; time_t expiryt = -1, deliveryt = -1; Octstr *qf = NULL, *xver = NULL, *mmc_id = NULL, *qdir = NULL; int msize = h->body ? octstr_len(h->body) : 0; int dlr; int mtype; debug("mmsbox.mm7eaif.sendinterface", 0, " --> Enterred eaif send interface, blen=[%d] <--- ", msize); hfrom = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-From")); if (!h->body || /* A body is required, and must parse */ (m = mms_frombinary(h->body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Unexpected MMS message, no body?"); goto done; } /* XXXX handle delivery reports differently. */ mtype = mms_messagetype(m); mh = mms_message_headers(m); /* Now get sender and receiver data. * for now we ignore adaptation flags. */ mms_collect_envdata_from_msgheaders(mh, &to, &subject, &otransid, &expiryt, &deliveryt, DEFAULT_EXPIRE, -1, octstr_get_cstr(unified_prefix), strip_prefixes); if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && gwlist_len(hto) > 0) { /* To address is in headers. */ int i, n; gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); to = gwlist_create(); for (i = 0, n = gwlist_len(hto); i < n; i++) { Octstr *h = NULL, *v = NULL; List *l; void *x; http_header_get(hto,i, &h, &v); l = http_header_split_value(v); while ((x = gwlist_extract_first(l)) != NULL) gwlist_append(to, x); gwlist_destroy(l, NULL); octstr_destroy(h); octstr_destroy(v); } } qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */ switch(mtype) { case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_RETRIEVE_CONF: /* Get Message ID */ if ((msgid = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-Message-Id"))) == NULL) msgid = http_header_value(mh, octstr_imm("Message-ID")); else mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); /* replace it in the message.*/ 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; if (deliveryt < 0) deliveryt = time(NULL); if (expiryt < 0) expiryt = time(NULL) + DEFAULT_EXPIRE; if (hfrom == NULL) hfrom = http_header_value(mh, octstr_imm("From")); 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"); MOD_SUBJECT(m, h->m, hfrom); /* Save it, put message id in header, return. */ qf = qfs->mms_queue_add(hfrom, to, subject, h->m->id, mmc_id, deliveryt, expiryt, m, NULL, NULL, NULL, NULL, NULL, NULL, dlr, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_DELIVERY_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report", value, rqh, NULL, 0, msgid); if (value2 && mmc_id == NULL) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("DeliveryReport", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_READ_ORIG_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, rqh, NULL, 0, msgid); if (value2 && mmc_id == NULL) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; } done: xver = octstr_format(EAIF_VERSION, h->m->ver.major, h->m->ver.minor1); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); octstr_destroy(xver); http_send_reply(h->client, hstatus, rh, octstr_imm("")); http_destroy_headers(hto); http_destroy_headers(rqh); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(hfrom); octstr_destroy(subject); octstr_destroy(otransid); octstr_destroy(msgid); octstr_destroy(qf); octstr_destroy(mmc_id); octstr_destroy(rr_uri); http_destroy_headers(mh); mms_destroy(m); return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; }
/* * Our WSP headers: Push Id, PDU type, headers, charset. */ static int ota_pack_push_headers(Msg **msg, Octstr *mime_type, Octstr *sec, Octstr *pin, Octstr *ota_binary) { (*msg)->sms.msgdata = octstr_create(""); if (octstr_case_compare(mime_type, octstr_imm("settings")) == 0) { /* PUSH ID, PDU type, header length, value length */ octstr_append_from_hex((*msg)->sms.msgdata, "01062C1F2A"); /* MIME type for settings */ octstr_format_append((*msg)->sms.msgdata, "%s", "application/x-wap-prov.browser-settings"); octstr_append_from_hex((*msg)->sms.msgdata, "00"); /* charset UTF-8 */ octstr_append_from_hex((*msg)->sms.msgdata, "81EA"); } else if (octstr_case_compare(mime_type, octstr_imm("bookmarks")) == 0) { /* PUSH ID, PDU type, header length, value length */ octstr_append_from_hex((*msg)->sms.msgdata, "01062D1F2B"); /* MIME type for bookmarks */ octstr_format_append((*msg)->sms.msgdata, "%s", "application/x-wap-prov.browser-bookmarks"); octstr_append_from_hex((*msg)->sms.msgdata, "00"); /* charset UTF-8 */ octstr_append_from_hex((*msg)->sms.msgdata, "81EA"); } else if (octstr_case_compare(mime_type, octstr_imm("syncsettings")) == 0) { octstr_append_from_hex((*msg)->sms.msgdata, "3406060502020b81EA"); } else if (octstr_case_compare(mime_type, octstr_imm("oma-settings")) == 0) { Octstr *hdr = octstr_create(""), *mac; unsigned char *p; unsigned int mac_len; #ifdef HAVE_LIBSSL unsigned char macbuf[EVP_MAX_MD_SIZE]; #endif /* PUSH ID, PDU type, header length, value length */ octstr_append_from_hex((*msg)->sms.msgdata, "0106"); octstr_append_from_hex(hdr, "1f2db6"); /* Content type + other type + sec param */ wsp_pack_short_integer(hdr, 0x11); if (octstr_case_compare(sec, octstr_imm("netwpin")) == 0) wsp_pack_short_integer(hdr, 0x0); else if (octstr_case_compare(sec, octstr_imm("userpin")) == 0) wsp_pack_short_integer(hdr, 0x01); else if (octstr_case_compare(sec, octstr_imm("usernetwpin")) == 0) wsp_pack_short_integer(hdr, 0x02); else if (octstr_case_compare(sec, octstr_imm("userpinmac")) == 0) wsp_pack_short_integer(hdr, 0x03); /* XXXX Although not quite supported now.*/ else { warning(0, "OMA ProvCont: Unknown SEC pin type '%s'.", octstr_get_cstr(sec)); wsp_pack_short_integer(hdr, 0x01); } wsp_pack_short_integer(hdr, 0x12); /* MAC */ #ifdef HAVE_LIBSSL p = HMAC(EVP_sha1(), octstr_get_cstr(pin), octstr_len(pin), (unsigned char *)octstr_get_cstr(ota_binary), octstr_len(ota_binary), macbuf, &mac_len); #else mac_len = 0; p = ""; warning(0, "OMA ProvCont: No SSL Support, '%s' not supported!", octstr_get_cstr(mime_type)); #endif mac = octstr_create_from_data((char *)p, mac_len); octstr_binary_to_hex(mac, 1); octstr_append(hdr, mac); octstr_append_from_hex(hdr, "00"); octstr_append_uintvar((*msg)->sms.msgdata, octstr_len(hdr)); octstr_append((*msg)->sms.msgdata, hdr); octstr_destroy(hdr); octstr_destroy(mac); } else { warning(0, "Unknown MIME type in OTA request, type '%s' is unsupported.", octstr_get_cstr(mime_type)); return 0; } return 1; }