static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh, *ph = NULL; Octstr *body = NULL, *rbody = NULL; Octstr *mms; MIMEEntity *form_data = make_multipart_formdata(); mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] 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)); mms = mms_tobinary(m); add_multipart_form_field(form_data, "to", "text/plain", NULL, to); add_multipart_form_field(form_data, "from", "text/plain", NULL, from); add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms); rh = mime_entity_headers(form_data); body = mime_entity_body(form_data); 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 { ret = rbody ? octstr_duplicate(rbody) : NULL; if (ret) octstr_strip_blanks(ret); } *retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(mms); mime_entity_destroy(form_data); return ret; }
void mms_queue_free_envelope(MmsEnvelope *e) { MmsEnvelopeTo *x; if (e == NULL) return; octstr_destroy(e->msgId); while ((x = gwlist_extract_first(e->to)) != NULL) { octstr_destroy(x->rcpt); gw_free(x); } gwlist_destroy(e->to, NULL); octstr_destroy(e->from); octstr_destroy(e->fromproxy); octstr_destroy(e->mdata); octstr_destroy(e->viaproxy); octstr_destroy(e->token); octstr_destroy(e->subject); octstr_destroy(e->vaspid); octstr_destroy(e->vasid); octstr_destroy(e->url1); octstr_destroy(e->url2); http_destroy_headers(e->hdrs); gw_free(e); }
static void start_push(HTTPCaller *caller, long i) { List *push_headers; Octstr *push_content; long *id; push_content = push_content_create(); push_headers = push_headers_create(octstr_len(push_content)); if (verbose) { debug("test.ppg", 0, "we have push content"); octstr_dump(push_content, 0); debug("test.ppg", 0, "and headers"); http_header_dump(push_headers); } id = gw_malloc(sizeof(long)); *id = i; make_url(&push_url); debug("test.ppg", 0, "TEST_PPG: starting to push job %ld", i); http_start_request(caller, HTTP_METHOD_POST, push_url, push_headers, push_content, 0, id, ssl_client_certkey_file); debug("test.ppg", 0, "push done"); octstr_destroy(push_content); http_destroy_headers(push_headers); }
static Octstr *make_connectreply_pdu(WSPMachine *m) { WSP_PDU *pdu; Octstr *os; List *caps; List *reply_headers; pdu = wsp_pdu_create(ConnectReply); pdu->u.ConnectReply.sessionid = m->session_id; caps = make_capabilities_reply(m); pdu->u.ConnectReply.capabilities = wsp_cap_pack_list(caps); wsp_cap_destroy_list(caps); reply_headers = make_reply_headers(m); pdu->u.ConnectReply.headers = wsp_headers_pack(reply_headers, 0, m->encoding_version); http_destroy_headers(reply_headers); os = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); return os; }
static WSP_PDU *make_push_pdu(WAPEvent *e) { WSP_PDU *pdu; List *headers; pdu = wsp_pdu_create(Push); /* * Both push headers and push body are optional */ if (e->u.S_Push_Req.push_headers == NULL) { headers = http_create_empty_headers(); pdu->u.Push.headers = wsp_headers_pack(headers, 1, WSP_1_2); http_destroy_headers(headers); } else pdu->u.Push.headers = wsp_headers_pack(e->u.S_Push_Req.push_headers, 1, WSP_1_2); if (e->u.S_Push_Req.push_body == NULL) pdu->u.Push.data = octstr_create(""); else pdu->u.Push.data = octstr_duplicate(e->u.S_Push_Req.push_body); return pdu; }
/* Replace top-level MIME headers: Old ones removed completetly */ void mime_replace_headers(MIMEEntity *e, List *headers) { gw_assert(e != NULL); gw_assert(headers != NULL); http_destroy_headers(e->headers); e->headers = http_header_duplicate(headers); e->start = NULL; /* clear it, since header change means it could have changed.*/ }
static void http_thread(void *arg) { HTTPClient *client; Octstr *ip; Octstr *url; List *headers; Octstr *body; List *cgivars; Octstr *reply_body = octstr_create( "<?xml version=\"1.0\"?>\n" "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"\n" " \"http://www.wapforum.org/DTD/wml_1.1.xml\">\n" "<wml>\n" "<card id=\"main\" title=\"Hello, world\" newcontext=\"true\">\n" " <p>Hello, world.</p>\n" "</card></wml>\n"); List *reply_headers = list_create(); int port; port = *(int *) arg; gw_free(arg); list_append(reply_headers, octstr_create("Content-Type: text/vnd.wap.wml")); for (;!dying;) { client = http_accept_request(port, &ip, &url, &headers, &body, &cgivars); if (client == NULL) break; http_send_reply(client, HTTP_OK, reply_headers, reply_body); http_destroy_headers(headers); octstr_destroy(ip); octstr_destroy(url); octstr_destroy(body); http_destroy_cgiargs(cgivars); } octstr_destroy(reply_body); http_destroy_headers(reply_headers); }
static void client_thread(void *arg) { List *reqh; unsigned long i; long succeeded, failed; HTTPCaller *caller; char buf[1024]; long in_queue; Counter *counter = NULL; caller = arg; succeeded = 0; failed = 0; reqh = gwlist_create(); sprintf(buf, "%ld", (long) gwthread_self()); http_header_add(reqh, "X-Thread", buf); if (auth_username != NULL && auth_password != NULL) http_add_basic_auth(reqh, auth_username, auth_password); in_queue = 0; counter = counter_create(); for (;;) { i = counter_increase(counter); if (i >= max_requests) goto receive_rest; start_request(caller, reqh, i); if (interval > 0) gwthread_sleep(interval); ++in_queue; if (receive_reply(caller) == -1) ++failed; else ++succeeded; --in_queue; } receive_rest: while (in_queue > 0) { if (receive_reply(caller) == -1) ++failed; else ++succeeded; --in_queue; } counter_destroy(counter); http_destroy_headers(reqh); http_caller_destroy(caller); info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed); }
/* helper function for queueing delivery reports. */ static int queue_dlr(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgid, Octstr *status, char *interf, List *errl) { Octstr *mmc_id = NULL, *qdir; MmsMsg *m = mms_deliveryreport(msgid, from, to, time(NULL), status); List *lto = gwlist_create(); int ret; Octstr *qf, *rr_uri = NULL; List *rqh = http_create_empty_headers(); if (errl) http_header_combine(rqh, errl); /* add status stuff. */ gwlist_append(lto, octstr_duplicate(to)); qdir = get_mmsbox_queue_dir(from, lto, mmc, &mmc_id); /* get routing info. */ rr_uri = mmsbox_get_report_info(m, mmc, mmc_id, "delivery-report", status, rqh, NULL, 0, msgid); qf = qfs->mms_queue_add(from, lto, NULL, mmc ? mmc->id : NULL, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), interf, NULL); if (qf) { /* Log to access log */ mms_log("Received DLR", from, lto, -1, msgid, status, mmc ? mmc->id : NULL, "MMSBox", NULL, NULL); ret = 0; } else ret = -1; octstr_destroy(qf); http_destroy_headers(rqh); octstr_destroy(rr_uri); gwlist_destroy(lto, (void *)octstr_destroy); octstr_destroy(mmc_id); mms_destroy(m); return ret; }
/* * Pack contact points and application id list into sia content type. It is * defined in ota, p. 18. */ static Octstr *pack_sia(List *headers) { Octstr *sia_content; WSP_PDU *pdu; pdu = wsp_pdu_create(sia); pdu->u.sia.version = CURRENT_VERSION; pdu->u.sia.application_id_list = pack_appid_list(headers); pdu->u.sia.contactpoints = pack_server_address(); sia_content = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); http_destroy_headers(headers); return sia_content; }
static void dispatch_mm7_recv(List *rl) { MmsBoxHTTPClientInfo *h; while ((h = gwlist_consume(rl)) != NULL) { int ret = -1, has_auth = 0; MmscGrp *m = h->m; if (auth_check(m->incoming.user, m->incoming.pass, h->headers, &has_auth) != 0) { /* Ask it to authenticate... */ List *hh = http_create_empty_headers(); http_header_add(hh, "WWW-Authenticate", "Basic realm=\"" MM_NAME "\""); http_send_reply(h->client, HTTP_UNAUTHORIZED, hh, octstr_imm("Authentication failed")); http_destroy_headers(hh); if (!has_auth) mms_info_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]", m->id ? octstr_get_cstr(m->id) : "(none)"); else mms_error_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]", m->id ? octstr_get_cstr(m->id) : "(none)"); } else if (h->m->type == SOAP_MMSC) ret = mm7soap_receive(h); else if (h->m->type == EAIF_MMSC) ret = mm7eaif_receive(h); else ret = mm7http_receive(h); h->m->last_pdu = time(NULL); if (ret == 0) h->m->mo_pdus++; else h->m->mo_errors++; free_mmsbox_http_clientInfo(h, 1); } }
static Octstr *make_resume_reply_pdu(WSPMachine *m, List *headers) { WSP_PDU *pdu; Octstr *os; pdu = wsp_pdu_create(Reply); /* Not specified for Resume replies */ pdu->u.Reply.status = wsp_convert_http_status_to_wsp_status(HTTP_OK); if (headers == NULL) { headers = http_create_empty_headers(); pdu->u.Reply.headers = wsp_headers_pack(headers, 1, m->encoding_version); http_destroy_headers(headers); } else { pdu->u.Reply.headers = wsp_headers_pack(headers, 1, m->encoding_version); } pdu->u.Reply.data = octstr_create(""); os = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); return os; }
static int kannel_send_sms(SMSCConn *conn, Msg *sms) { ConnData *conndata = conn->data; Octstr *url; List *headers; if (!conndata->no_sep) { url = octstr_format("%S?" "username=%E&password=%E&to=%E&text=%E", conndata->send_url, conndata->username, conndata->password, sms->sms.receiver, sms->sms.msgdata); } else { Octstr *msgdata = octstr_duplicate(sms->sms.msgdata); octstr_binary_to_hex(msgdata, HEX_NOT_UPPERCASE); url = octstr_format("%S?" "username=%E&password=%E&to=%E&text=%S", conndata->send_url, conndata->username, conndata->password, sms->sms.receiver, msgdata); octstr_destroy(msgdata); } if (octstr_len(sms->sms.udhdata)) { if (!conndata->no_sep) { octstr_format_append(url, "&udh=%E", sms->sms.udhdata); } else { Octstr *udhdata = octstr_duplicate(sms->sms.udhdata); octstr_binary_to_hex(udhdata, HEX_NOT_UPPERCASE); octstr_format_append(url, "&udh=%S", udhdata); octstr_destroy(udhdata); } } if (!conndata->no_sender) octstr_format_append(url, "&from=%E", sms->sms.sender); if (sms->sms.mclass != MC_UNDEF) octstr_format_append(url, "&mclass=%d", sms->sms.mclass); if (!conndata->no_coding && sms->sms.coding != DC_UNDEF) octstr_format_append(url, "&coding=%d", sms->sms.coding); /* Obey that smsbox's sendsms HTTP interface is still expecting * WINDOWS-1252 as default charset, while all other internal parts * use UTF-8 as internal encoding. This means, when we pass a SMS * into a next Kannel instance, we need to let the smsbox know which * charset we have in use. * XXX TODO: change smsbox interface to use UTF-8 as default * in next major release. */ if (sms->sms.coding == DC_7BIT) octstr_append_cstr(url, "&charset=UTF-8"); else if (sms->sms.coding == DC_UCS2) octstr_append_cstr(url, "&charset=UTF-16BE"); if (sms->sms.mwi != MWI_UNDEF) octstr_format_append(url, "&mwi=%d", sms->sms.mwi); if (sms->sms.account) /* prepend account with local username */ octstr_format_append(url, "&account=%E:%E", sms->sms.service, sms->sms.account); if (sms->sms.binfo) /* prepend billing info */ octstr_format_append(url, "&binfo=%S", sms->sms.binfo); if (sms->sms.smsc_id) /* proxy the smsc-id to the next instance */ octstr_format_append(url, "&smsc=%S", sms->sms.smsc_id); if (conndata->dlr_url) { char id[UUID_STR_LEN + 1]; Octstr *mid; /* create Octstr from UUID */ uuid_unparse(sms->sms.id, id); mid = octstr_create(id); octstr_format_append(url, "&dlr-url=%E", conndata->dlr_url); /* encapsulate the original DLR-URL, escape code for DLR mask * and message id */ octstr_format_append(url, "%E%E%E%E%E", octstr_imm("&dlr-url="), sms->sms.dlr_url != NULL ? sms->sms.dlr_url : octstr_imm(""), octstr_imm("&dlr-mask=%d"), octstr_imm("&dlr-mid="), mid); octstr_destroy(mid); } else if (sms->sms.dlr_url != NULL) octstr_format_append(url, "&dlr-url=%E", sms->sms.dlr_url); if (sms->sms.dlr_mask != DLR_UNDEFINED && sms->sms.dlr_mask != DLR_NOTHING) octstr_format_append(url, "&dlr-mask=%d", sms->sms.dlr_mask); if (sms->sms.validity != SMS_PARAM_UNDEFINED) octstr_format_append(url, "&validity=%ld", (sms->sms.validity - time(NULL)) / 60); if (sms->sms.deferred != SMS_PARAM_UNDEFINED) octstr_format_append(url, "&deferred=%ld", (sms->sms.deferred - time(NULL)) / 60); headers = gwlist_create(); debug("smsc.http.kannel", 0, "HTTP[%s]: Start request", octstr_get_cstr(conn->id)); http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, NULL, 0, sms, NULL); octstr_destroy(url); http_destroy_headers(headers); return 0; }
/* * Thread to handle finished sendings */ static void httpsmsc_send_cb(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; Msg *msg; int status; List *headers; Octstr *final_url, *body; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) { msg = http_receive_result(conndata->http_ref, &status, &final_url, &headers, &body); if (msg == NULL) break; /* they told us to die, by unlocking */ counter_decrease(conndata->open_sends); if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); /* Handle various states here. */ /* request failed and we are not in shutdown mode */ if (status == -1 && conndata->shutdown == 0) { error(0, "HTTP[%s]: Couldn't connect to SMS center." "(retrying in %ld seconds) %ld.", octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); /* XXX how should we know whether it's temp. error ?? */ bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); /* * Just sleep reconnect delay and set conn to ACTIVE again; * otherwise if no pending request are here, we leave conn in * RECONNECTING state for ever and no routing (trials) take place. */ if (counter_value(conndata->open_sends) == 0) { gwthread_sleep(conn->reconnect_delay); /* and now enable routing again */ mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } continue; } /* request failed and we *are* in shutdown mode, drop the message */ else if (status == -1 && conndata->shutdown == 1) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } /* request succeeded */ else { /* we received a response, so this link is considered online again */ if (conn->status != SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } conndata->callbacks->parse_reply(conn, msg, status, headers, body); } http_destroy_headers(headers); octstr_destroy(final_url); octstr_destroy(body); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; if (counter_value(conndata->open_sends)) { warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.", octstr_get_cstr(conn->id), counter_value(conndata->open_sends)); } }
/* * Thread to listen to HTTP requests from SMSC entity */ static void httpsmsc_receiver(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; HTTPClient *client; Octstr *ip, *url, *body; List *headers, *cgivars; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while (conndata->shutdown == 0) { /* reset */ ip = url = body = NULL; headers = cgivars = NULL; /* XXX if conn->is_stopped, do not receive new messages.. */ client = http_accept_request(conndata->port, &ip, &url, &headers, &body, &cgivars); if (client == NULL) break; if (cgivars != NULL) { octstr_append_char(url, '?'); http_cgivar_dump_into(cgivars, url); } debug("smsc.http", 0, "HTTP[%s]: Got request `%s'", octstr_get_cstr(conn->id), octstr_get_cstr(url)); if (connect_denied(conndata->allow_ip, ip)) { info(0, "HTTP[%s]: Connection `%s' tried from denied " "host %s, ignored", octstr_get_cstr(conn->id), octstr_get_cstr(url), octstr_get_cstr(ip)); http_close_client(client); } else conndata->callbacks->receive_sms(conn, client, headers, body, cgivars); debug("smsc.http", 0, "HTTP[%s]: Destroying client information", octstr_get_cstr(conn->id)); octstr_destroy(url); octstr_destroy(ip); octstr_destroy(body); http_destroy_headers(headers); http_destroy_cgiargs(cgivars); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; http_close_port(conndata->port); /* unblock http_receive_result() if there are no open sends */ if (counter_value(conndata->open_sends) == 0) http_caller_signal_shutdown(conndata->http_ref); if (conndata->sender_thread != -1) { gwthread_wakeup(conndata->sender_thread); gwthread_join(conndata->sender_thread); } if (conndata->send_cb_thread != -1) { gwthread_wakeup(conndata->send_cb_thread); gwthread_join(conndata->send_cb_thread); } mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; mutex_unlock(conn->flow_mutex); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); bb_smscconn_killed(); }
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 void httpd_serve(HTTPClient *client, Octstr *ourl, List *headers, Octstr *body, List *cgivars) { Octstr *reply, *final_reply, *url; char *content_type; char *header, *footer; int status_type; int i; long pos; reply = final_reply = NULL; /* for compiler please */ url = octstr_duplicate(ourl); /* Set default reply format according to client * Accept: header */ if (http_type_accepted(headers, "text/vnd.wap.wml")) { status_type = BBSTATUS_WML; content_type = "text/vnd.wap.wml"; } else if (http_type_accepted(headers, "text/html")) { status_type = BBSTATUS_HTML; content_type = "text/html"; } else if (http_type_accepted(headers, "text/xml")) { status_type = BBSTATUS_XML; content_type = "text/xml"; } else { status_type = BBSTATUS_TEXT; content_type = "text/plain"; } /* kill '/cgi-bin' prefix */ pos = octstr_search(url, octstr_imm("/cgi-bin/"), 0); if (pos != -1) octstr_delete(url, pos, 9); else if (octstr_get_char(url, 0) == '/') octstr_delete(url, 0, 1); /* look for type and kill it */ pos = octstr_search_char(url, '.', 0); if (pos != -1) { Octstr *tmp = octstr_copy(url, pos+1, octstr_len(url) - pos - 1); octstr_delete(url, pos, octstr_len(url) - pos); if (octstr_str_compare(tmp, "txt") == 0) status_type = BBSTATUS_TEXT; else if (octstr_str_compare(tmp, "html") == 0) status_type = BBSTATUS_HTML; else if (octstr_str_compare(tmp, "xml") == 0) status_type = BBSTATUS_XML; else if (octstr_str_compare(tmp, "wml") == 0) status_type = BBSTATUS_WML; octstr_destroy(tmp); } for (i=0; httpd_commands[i].command != NULL; i++) { if (octstr_str_compare(url, httpd_commands[i].command) == 0) { reply = httpd_commands[i].function(cgivars, status_type); break; } } /* check if command found */ if (httpd_commands[i].command == NULL) { char *lb = bb_status_linebreak(status_type); reply = octstr_format("Unknown command `%S'.%sPossible commands are:%s", ourl, lb, lb); for (i=0; httpd_commands[i].command != NULL; i++) octstr_format_append(reply, "%s%s", httpd_commands[i].command, lb); } gw_assert(reply != NULL); if (status_type == BBSTATUS_HTML) { header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" "<html>\n<title>" GW_NAME "</title>\n<body>\n<p>"; footer = "</p>\n</body></html>\n"; content_type = "text/html"; } else if (status_type == BBSTATUS_WML) { header = "<?xml version=\"1.0\"?>\n" "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" " "\"http://www.wapforum.org/DTD/wml_1.1.xml\">\n" "\n<wml>\n <card>\n <p>"; footer = " </p>\n </card>\n</wml>\n"; content_type = "text/vnd.wap.wml"; } else if (status_type == BBSTATUS_XML) { header = "<?xml version=\"1.0\"?>\n" "<gateway>\n"; footer = "</gateway>\n"; } else { header = ""; footer = ""; content_type = "text/plain"; } final_reply = octstr_create(header); octstr_append(final_reply, reply); octstr_append_cstr(final_reply, footer); /* debug("bb.http", 0, "Result: '%s'", octstr_get_cstr(final_reply)); */ http_destroy_headers(headers); headers = list_create(); http_header_add(headers, "Content-Type", content_type); http_send_reply(client, HTTP_OK, headers, final_reply); octstr_destroy(url); octstr_destroy(ourl); octstr_destroy(body); octstr_destroy(reply); octstr_destroy(final_reply); http_destroy_headers(headers); http_destroy_cgiargs(cgivars); }
int main(int argc, char *argv[]) { Octstr *fname, *s; int cfidx; int msize; List *h = NULL; if (argc < 2) return -1; mms_lib_init(); cfidx = get_and_set_debugs(argc, argv, find_own); if (argv[cfidx] == NULL) fname = octstr_imm("mmsc.conf"); else fname = octstr_create(argv[cfidx]); mms_info(0, "mmssend", NULL, "----------------------------------------"); mms_info(0, "mmssend", NULL, " MMSC Message sender runner version %s starting", MMSC_VERSION); /* Load settings. */ settings = mms_load_mmsc_settings(fname, &proxyrelays,1); if (!settings) panic(0, "No global MMSC configuration, or failed to read conf from <%s>!", octstr_get_cstr(fname)); octstr_destroy(fname); if (from == NULL || to == NULL) { mms_error(0, "mmssend", NULL, "Sender and recipient addresses required!\n"); exit(-1); } else { /* fix up 'to' list */ List *l = gwlist_create(); Octstr *x; while ((x = gwlist_extract_first(to)) != NULL) { octstr_strip_blanks(x); _mms_fixup_address(&x, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); gwlist_append(l, x); } gwlist_destroy(to, NULL); to = l; } /* fix from address. */ _mms_fixup_address(&from, settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL, settings->strip_prefixes, 1); #if 0 mms_start_profile_engine(octstr_get_cstr(settings->ua_profile_cache_dir)); #endif if (data) { /* try and detect if we are looking at plain text (mime-encoded) or binary encoded message. */ int ch = octstr_get_char(data, 0); if (isprint(ch)) { MIMEEntity *mime = mime_octstr_to_entity(data); if (mime) { m = mms_frommime(mime); mime_entity_destroy(mime); } } else m = mms_frombinary_ex(data, from ? from : octstr_imm("anon@anon"), octstr_get_cstr(settings->unified_prefix), settings->strip_prefixes); if (m) mms_msgdump(m,1); msize = octstr_len(data); octstr_destroy(data); } else msize = 0; if (!m) panic(0, "No Message supplied, or failed to decode binary data!"); h = http_create_empty_headers(); http_header_add(h, "X-Mbuni-Tool", "mmssend"); http_header_add(h, "X-Mbuni-CalledFrom", "Terminal"); if (binfo) { mms_info(0, "add.info", NULL, "Adding extra headers billing info `X-Mms-Binfo' :"); http_header_add(h, "X-Mms-Binfo", octstr_get_cstr(binfo)); } s = settings->qfs->mms_queue_add(from, to, NULL, NULL, NULL, time(NULL), time(NULL) + settings->default_msgexpiry, m, NULL, NULL, NULL, NULL, NULL, h, dlr, octstr_get_cstr(settings->global_queuedir), "MM3", settings->host_alias); if (savetommbox) mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir), octstr_get_cstr(from), m, NULL, octstr_imm("Sent")); mms_log("Received", from, to, msize, s, NULL, NULL, "MM3",NULL,NULL); printf("Queued: %s, mmbox=%s\n", octstr_get_cstr(s), mmbox ? octstr_get_cstr(mmbox) : ""); octstr_destroy(s); http_destroy_headers(h); mms_cleanup_mmsc_settings(settings); mms_lib_shutdown(); return 0; }
static int sendMsg(MmsEnvelope *e) { MmsMsg *msg = NULL; int i, n; Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL; if ((msg = qfs->mms_queue_getdata(e)) == NULL) { mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname); goto done2; } for (i = 0, n = gwlist_len(e->to); i<n; i++) { int res = MMS_SEND_OK; MmsEnvelopeTo *to = gwlist_get(e->to, i); Octstr *err = NULL; time_t tnow = time(NULL); MmscGrp *mmc = NULL; Octstr *new_msgid = NULL; List *errl = NULL; int is_email = 0; if (!to || !to->process) continue; if (e->expiryt != 0 && /* Handle message expiry. */ e->expiryt < tnow) { err = octstr_format("MMSC error: Message expired while sending to %S!", to->rcpt); res = MMS_SEND_ERROR_FATAL; goto done; } else if (e->attempts >= maxsendattempts) { err = octstr_format("MMSBox error: Failed to deliver to " "%S after %ld attempts. (max attempts allowed is %ld)!", to->rcpt, e->attempts, maxsendattempts); res = MMS_SEND_ERROR_FATAL; goto done; } is_email = (octstr_search_char(to->rcpt, '@', 0) > 0); if ((mmc = get_handler_mmc(e->viaproxy, to->rcpt, e->from)) == NULL && !is_email) { err = octstr_format("MMSBox error: Failed to deliver to " "%S. Don't know how to route!", to->rcpt); res = MMS_SEND_ERROR_TRANSIENT; goto done; } if (is_email) { int j = octstr_case_search(e->from, octstr_imm("/TYPE=PLMN"), 0); int k = octstr_case_search(e->from, octstr_imm("/TYPE=IPv"), 0); int len = octstr_len(e->from); Octstr *pfrom; if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) pfrom = octstr_copy(e->from, 0, j); else if (k > 0 && k + sizeof "/TYPE=IPv" == len) pfrom = octstr_copy(e->from, 0, k); else pfrom = octstr_duplicate(e->from); if (octstr_search_char(e->from, '@', 0) < 0) octstr_format_append(pfrom,"@%S", myhostname); res = mms_sendtoemail(pfrom, to->rcpt, e->subject ? e->subject : octstr_imm(""), e->msgId, msg, 0, &err, octstr_get_cstr(sendmail_cmd), myhostname, 0, 0, "", "", 0, e->xqfname, e->hdrs); octstr_destroy(pfrom); } else { res = mms_sendtommsc(mmc, e, to->rcpt, otransid, msg, &new_msgid, &errl); if (errl) err = http_header_value(errl, octstr_imm("X-Mbuni-Error")); } if (mmc) { if (res == MMS_SEND_OK) mmc->mt_pdus++; else mmc->mt_errors++; mmc->last_pdu = time(NULL); return_mmsc_conn(mmc); /* important. */ } done: if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) { to->process = 0; if (e->msgtype == MMS_MSGTYPE_SEND_REQ || e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */ queue_dlr(mmc, e->from, to->rcpt, new_msgid, octstr_imm("Forwarded"), "MM7-Out", errl); } else if (res == MMS_SEND_ERROR_FATAL && mmc) { if (e->msgtype == MMS_MSGTYPE_SEND_REQ || e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */ queue_dlr(mmc, e->from, to->rcpt, e->msgId, (e->expiryt != 0 && e->expiryt < tnow) ? octstr_imm("Expired") : octstr_imm("Rejected"), "MM7-Out", errl); } if (res == MMS_SEND_ERROR_FATAL) to->process = 0; /* No more attempts. */ /* handle CDR */ if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED || res == MMS_SEND_ERROR_FATAL) { Octstr *mclass = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class")); Octstr *prio = mms_get_header_value(msg, octstr_imm("X-Mms-Priority")); Octstr *mstatus = mms_get_header_value(msg, octstr_imm("X-Mms-Status")); /* Do CDR */ cdrfs->logcdr(e->created, octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), octstr_get_cstr(e->msgId), mmc ? octstr_get_cstr(mmc->id) : NULL, /* Should we touch mmc here? XXX */ e->src_interface, "MM7", e->msize, (char *)mms_message_type_to_cstr(e->msgtype), prio ? octstr_get_cstr(prio) : NULL, mclass ? octstr_get_cstr(mclass) : NULL, res == MMS_SEND_ERROR_FATAL ? "dropped" : (mstatus ? octstr_get_cstr(mstatus) : "sent"), e->dlr, 0); octstr_destroy(mclass); octstr_destroy(prio); octstr_destroy(mstatus); } if (err == NULL) mms_info(0, "MM7", NULL, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: msgid=[%s]", SEND_ERROR_STR(res), octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize, new_msgid ? octstr_get_cstr(new_msgid) : "N/A"); else mms_error_ex("MT", 0, "MM7", NULL, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: %s", SEND_ERROR_STR(res), octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize, octstr_get_cstr(err)); octstr_destroy(new_msgid); octstr_destroy(err); http_destroy_headers(errl); e->lasttry = tnow; if (qfs->mms_queue_update(e) == 1) { e = NULL; break; /* Queue entry gone. */ } } done2: mms_destroy(msg); octstr_destroy(otransid); if (e) { /* Update the queue if it is still valid (e.g. recipients not handled) * XXX can this happen here??... */ e->lasttry = time(NULL); e->attempts++; /* Update count of number of delivery attempts. */ e->sendt = e->lasttry + mmsbox_send_back_off * e->attempts; if (qfs->mms_queue_update(e) != 1) qfs->mms_queue_free_env(e); } return 1; /* always delete queue entry. */ }
static int sendNotify(MmsEnvelope *e) { Octstr *to; MmsMsg *msg, *smsg = NULL; MmsEnvelopeTo *xto = gwlist_get(e->to, 0); Octstr *err = NULL; time_t tnow = time(NULL); int j, k, len; Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy; int mtype, msize; int res = MMS_SEND_OK, dlr; time_t expiryt; char *prov_notify_event = NULL; char *rtype = NULL; if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */ e->sendt = e->expiryt + 3600*24*30*12; info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping", e->xqfname); return settings->qfs->mms_queue_update(e); } if (!xto) { error(0, "mobilesender: Queue entry %s with no recipients!", e->xqfname); return 0; } msg = settings->qfs->mms_queue_getdata(e); to = octstr_duplicate(xto->rcpt); expiryt = e->expiryt; msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL; from = octstr_duplicate(e->from); fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL; msize = e->msize; dlr = e->dlr; if (e->expiryt != 0 && /* Handle message expiry. */ e->expiryt < tnow) { err = octstr_format("MMSC error: Message expired while sending to %S!", to); res = MMS_SEND_ERROR_FATAL; prov_notify_event = "failedfetch"; rtype = "Expired"; goto done; } else if (e->attempts >= settings->maxsendattempts) { err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", to, e->attempts); res = MMS_SEND_ERROR_FATAL; prov_notify_event = "failedfetch"; rtype = "Expired"; goto done; } j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0); k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0); len = octstr_len(to); if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) { /* A proper number. */ phonenum = octstr_copy(to, 0, j); #if 0 normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum); #else mms_normalize_phonenum(&phonenum, octstr_get_cstr(settings->unified_prefix), settings->strip_prefixes); #endif } else if (k > 0 && k + sizeof "/TYPE=IPv" == len) rcpt_ip = octstr_copy(to, 0, k); else { /* We only handle phone numbers here. */ err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to)); res = MMS_SEND_ERROR_FATAL; goto done; } mtype = mms_messagetype(msg); /* For phone, getting here means the message can be delivered. So: * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req) * - If the recipient can't take MMS, then send SMS. */ /* We handle two types of requests: send and delivery/read notifications. * other types of messages cannot possibly be in this queue! */ if (mtype == MMS_MSGTYPE_SEND_REQ || mtype == MMS_MSGTYPE_RETRIEVE_CONF) { Octstr *url, *transid; if (phonenum) { int send_ind = mms_ind_send(settings->prov_getstatus, phonenum); if (send_ind < 0 && settings->notify_unprovisioned) send_ind = 0; if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */ res = MMS_SEND_ERROR_TRANSIENT; err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", phonenum); /* Do not increase delivery attempts counter. */ e->lasttry = tnow; e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts); if (settings->qfs->mms_queue_update(e) == 1) e = NULL; /* Queue entry gone. */ else settings->qfs->mms_queue_free_env(e); goto done; } else if (send_ind == 0) { /* provisioned but does not support */ Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt), from); if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */ List *pheaders; Octstr *sto = octstr_duplicate(phonenum); octstr_url_encode(s); octstr_url_encode(sto); url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto); pheaders = http_create_empty_headers(); http_header_add(pheaders, "Connection", "close"); http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION); http_start_request(httpcaller, HTTP_METHOD_GET, url, pheaders, NULL, 0, &edummy, NULL); http_destroy_headers(pheaders); octstr_destroy(url); octstr_destroy(sto); } else if (s) octstr_destroy(s); res = MMS_SEND_OK; err = octstr_imm("No MMS Ind support, sent SMS instead"); xto->process = 0; /* No more processing. */ if (settings->qfs->mms_queue_update(e) == 1) e = NULL; else settings->qfs->mms_queue_free_env(e); goto done; } } /* To get here means we can send Ind. */ url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE, phonenum ? phonenum : to, settings); info(0, "Preparing to notify client to fetch message at URL: %s", octstr_get_cstr(url)); transid = mms_maketransid(e->xqfname, settings->host_alias); smsg = mms_notification(msg, e->msize, url, transid, e->expiryt ? e->expiryt : tnow + settings->default_msgexpiry, settings->optimize_notification_size); octstr_destroy(transid); octstr_destroy(url); } else if (mtype == MMS_MSGTYPE_DELIVERY_IND || mtype == MMS_MSGTYPE_READ_ORIG_IND) smsg = msg; else { error(0, "Unexpected message type %s for %s found in MT queue!", mms_message_type_to_cstr(mtype), octstr_get_cstr(to)); res = MMS_SEND_ERROR_FATAL; goto done; } if (smsg) start_push(phonenum ? phonenum : rcpt_ip, phonenum ? 1 : 0, e, smsg); /* Send the message. * Don't touch 'e' after this point! * It may be freed by receive thread. */ if (smsg != msg && smsg) mms_destroy(smsg); done: if (err != NULL && res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error * queue it. */ if (dlr) { MmsMsg *m = mms_deliveryreport(msgId, to, tnow, rtype ? octstr_imm(rtype) : octstr_imm("Indeterminate")); List *l = gwlist_create(); Octstr *res; gwlist_append(l, from); /* Add to queue, switch via proxy to be from proxy. */ res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l, err, NULL, fromproxy, tnow, tnow+settings->default_msgexpiry, m, NULL, NULL, NULL, NULL, NULL, NULL, 0, octstr_get_cstr(settings->mm1_queuedir), "MM2", settings->host_alias); gwlist_destroy(l, NULL); mms_destroy(m); octstr_destroy(res); } } /* Write to log */ info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", SEND_ERROR_STR(res), octstr_get_cstr(from), octstr_get_cstr(to), msize, err ? octstr_get_cstr(err) : ""); if (res == MMS_SEND_ERROR_FATAL) { xto->process = 0; /* No more attempts to deliver, delete this. */ if (settings->qfs->mms_queue_update(e) == 1) e = NULL; /* Queue entry gone. */ else settings->qfs->mms_queue_free_env(e); } /* Else queue will be updated/freed elsewhere. */ if (prov_notify_event) notify_prov_server(octstr_get_cstr(settings->prov_notify), to ? octstr_get_cstr(to) : "unknown", prov_notify_event, rtype ? rtype : "", e ? e->msgId : NULL, NULL, NULL); if (msg) mms_destroy(msg); octstr_destroy(phonenum); octstr_destroy(rcpt_ip); octstr_destroy(to); octstr_destroy(msgId); octstr_destroy(fromproxy); octstr_destroy(from); octstr_destroy(err); return 1; }
static int receive_push_reply(HTTPCaller *caller) { int http_status; List *reply_headers = NULL; Octstr *final_url = NULL, *reply_body = NULL; MmsEnvelope *env; http_status = HTTP_UNAUTHORIZED; while ((env = http_receive_result_real(caller, &http_status, &final_url, &reply_headers, &reply_body,1)) != NULL) { MmsEnvelopeTo *xto = NULL; Octstr *to = NULL; if (http_status == -1 || final_url == NULL) { error(0, "push failed, no reason found"); goto push_failed; } if (env == &edummy) /* Skip this one it is a dummy. */ goto push_free_env; xto = gwlist_get(env->to, 0); if (xto) to = xto->rcpt; else { error(0, "mobilesender: Queue entry %s has no recipient address!", env->xqfname); goto push_failed; } info(0, "send2mobile.push_reply[%s]: From %s, to %s => %d", env->xqfname, octstr_get_cstr(env->from), octstr_get_cstr(to), http_status); if (http_status == HTTP_UNAUTHORIZED || http_status == HTTP_NOT_FOUND || http_status == HTTP_FORBIDDEN) { /* This is a temporary system error * do not increase attempts, count, * merely reschedule * for a minute or so later. */ error(0, "Deffered notification, WAP Push failed for " "msgid %s to %s, http error: %d!", octstr_get_cstr(env->msgId), octstr_get_cstr(to), http_status); goto push_failed; } debug("mobilesender.push", 0, "Push reply headers were"); http_header_dump(reply_headers); mms_log2("Notify", octstr_imm("system"), to, -1, env ? env->msgId : NULL, NULL, NULL, "MM1", NULL,NULL); if ((env = update_env_success(env, xto)) != NULL) goto push_free_env; /* Fall through. */ push_failed: env = update_env_failed(env); push_free_env: if (env && env != &edummy) settings->qfs->mms_queue_free_env(env); octstr_destroy(final_url); octstr_destroy(reply_body); http_destroy_headers(reply_headers); } return 0; }
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; }
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; }
static void kannel_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars) { ConnData *conndata = conn->data; Octstr *user, *pass, *from, *to, *text, *udh, *account, *binfo, *charset; Octstr *dlrmid, *dlrerr; Octstr *tmp_string, *retmsg; int mclass, mwi, coding, validity, deferred, dlrmask; List *reply_headers; int ret; mclass = mwi = coding = validity = deferred = dlrmask = SMS_PARAM_UNDEFINED; user = http_cgi_variable(cgivars, "username"); pass = http_cgi_variable(cgivars, "password"); from = http_cgi_variable(cgivars, "from"); to = http_cgi_variable(cgivars, "to"); text = http_cgi_variable(cgivars, "text"); udh = http_cgi_variable(cgivars, "udh"); charset = http_cgi_variable(cgivars, "charset"); account = http_cgi_variable(cgivars, "account"); binfo = http_cgi_variable(cgivars, "binfo"); dlrmid = http_cgi_variable(cgivars, "dlr-mid"); tmp_string = http_cgi_variable(cgivars, "flash"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mclass"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mclass); } tmp_string = http_cgi_variable(cgivars, "mwi"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &mwi); } tmp_string = http_cgi_variable(cgivars, "coding"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &coding); } tmp_string = http_cgi_variable(cgivars, "validity"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &validity); } tmp_string = http_cgi_variable(cgivars, "deferred"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &deferred); } tmp_string = http_cgi_variable(cgivars, "dlr-mask"); if (tmp_string) { sscanf(octstr_get_cstr(tmp_string),"%d", &dlrmask); } dlrerr = http_cgi_variable(cgivars, "dlr-err"); debug("smsc.http.kannel", 0, "HTTP[%s]: Received an HTTP request", octstr_get_cstr(conn->id)); if (user == NULL || pass == NULL || octstr_compare(user, conndata->username) != 0 || octstr_compare(pass, conndata->password) != 0) { error(0, "HTTP[%s]: Authorization failure", octstr_get_cstr(conn->id)); retmsg = octstr_create("Authorization failed for sendsms"); } else if (dlrmask != 0 && dlrmid != NULL) { /* we got a DLR, and we don't require additional values */ Msg *dlrmsg; dlrmsg = dlr_find(conn->id, dlrmid, /* message id */ to, /* destination */ dlrmask, 0); if (dlrmsg != NULL) { dlrmsg->sms.sms_type = report_mo; dlrmsg->sms.msgdata = octstr_duplicate(text); dlrmsg->sms.account = octstr_duplicate(conndata->username); debug("smsc.http.kannel", 0, "HTTP[%s]: Received DLR for DLR-URL <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(dlrmsg->sms.dlr_url)); if (dlrerr != NULL) { /* pass errorcode as is */ if (dlrmsg->sms.meta_data == NULL) dlrmsg->sms.meta_data = octstr_create(""); meta_data_set_value(dlrmsg->sms.meta_data, METADATA_DLR_GROUP, octstr_imm(METADATA_DLR_GROUP_ERRORCODE), dlrerr, 1); } ret = bb_smscconn_receive(conn, dlrmsg); if (ret == -1) retmsg = octstr_create("Not accepted"); else retmsg = octstr_create("Sent."); } else { error(0,"HTTP[%s]: Got DLR but could not find message or was not interested " "in it id<%s> dst<%s>, type<%d>", octstr_get_cstr(conn->id), octstr_get_cstr(dlrmid), octstr_get_cstr(to), dlrmask); retmsg = octstr_create("Unknown DLR, not accepted"); } } else if (from == NULL || to == NULL || text == NULL) { error(0, "HTTP[%s]: Insufficient args", octstr_get_cstr(conn->id)); retmsg = octstr_create("Insufficient args, rejected"); } else if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) { error(0, "HTTP[%s]: UDH field misformed, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field misformed, rejected"); } else if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) { error(0, "HTTP[%s]: UDH field is too long, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("UDH field is too long, rejected"); } else { /* we got a normal MO SMS */ Msg *msg; msg = msg_create(sms); debug("smsc.http.kannel", 0, "HTTP[%s]: Constructing new SMS", octstr_get_cstr(conn->id)); msg->sms.service = octstr_duplicate(user); msg->sms.sender = octstr_duplicate(from); msg->sms.receiver = octstr_duplicate(to); msg->sms.msgdata = octstr_duplicate(text); msg->sms.udhdata = octstr_duplicate(udh); msg->sms.smsc_id = octstr_duplicate(conn->id); msg->sms.time = time(NULL); msg->sms.mclass = mclass; msg->sms.mwi = mwi; msg->sms.coding = coding; msg->sms.validity = (validity == SMS_PARAM_UNDEFINED ? validity : time(NULL) + validity * 60); msg->sms.deferred = (deferred == SMS_PARAM_UNDEFINED ? deferred : time(NULL) + deferred * 60); msg->sms.account = octstr_duplicate(account); msg->sms.binfo = octstr_duplicate(binfo); /* re-encode content if necessary */ if (sms_charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) { error(0, "HTTP[%s]: Charset or body misformed, rejected", octstr_get_cstr(conn->id)); retmsg = octstr_create("Charset or body misformed, rejected"); } else { ret = bb_smscconn_receive(conn, msg); if (ret == -1) retmsg = octstr_create("Not accepted"); else retmsg = octstr_create("Sent."); } } reply_headers = gwlist_create(); http_header_add(reply_headers, "Content-Type", "text/plain"); debug("smsc.http.kannel", 0, "HTTP[%s]: Sending reply", octstr_get_cstr(conn->id)); http_send_reply(client, HTTP_ACCEPTED, reply_headers, retmsg); octstr_destroy(retmsg); http_destroy_headers(reply_headers); }
int main(int argc, char **argv) { Octstr *mime_content, *pap_content, *push_data, *rdf_content, *boundary, *push_content_file = NULL, *this_header, *pap_osname, *data_osname; List *content_headers, *source_parts; char *pap_content_file, *push_data_file, *rdf_content_file; int ret, std_out, opt, d_file, c_file; FILE *fp1, *fp2, *fp3; gwlib_init(); std_out = 0; d_file = 0; c_file = 0; data_osname = NULL; pap_osname = NULL; while ((opt = getopt(argc, argv, "hd:sc:")) != EOF) { switch(opt) { case 'h': help(); exit(1); break; case 'd': d_file = 1; data_osname = octstr_create(optarg); break; case 'c': c_file = 1; pap_osname = octstr_create(optarg); break; case 's': std_out = 1; break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping"); break; } } if (optind >= argc) { help(); panic(0, "missing arguments, stopping"); } if (!c_file) pap_content_file = "test/pap.txt"; else pap_content_file = octstr_get_cstr(pap_osname); if (!d_file) push_data_file = "test/data.txt"; else push_data_file = octstr_get_cstr(data_osname); rdf_content_file = "test/rdf.txt"; mime_content = octstr_read_file(argv[optind]); if (mime_content == NULL) { octstr_destroy(mime_content); error(0, "No MIME source"); panic(0, "Stopping"); } source_parts = octstr_split(mime_content, octstr_imm("content=")); if (gwlist_len(source_parts) == 1) { /* a hack to circumvent a bug */ error(0, "Badly formatted source:"); octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); panic(0, "Stopping"); } boundary = gwlist_extract_first(source_parts); octstr_delete(boundary, 0, octstr_len(octstr_imm("boundary="))); if (skip_tail(&boundary, ';') == 0) { error(0, "Cannot determine boundary, no delimiter; possible"); octstr_dump(boundary, 0); goto no_parse; } octstr_destroy(mime_content); mime_content = gwlist_extract_first(source_parts); if (skip_tail(&mime_content, ';') == 0){ error(0, "Cannot determine mime content, no delimiter"); octstr_dump(mime_content, 0); goto no_parse; } prepend_crlf(&mime_content); add_crs(mime_content); append_crlf(mime_content); ret = mime_parse(boundary, mime_content, &pap_content, &push_data, &content_headers, &rdf_content); if (ret == 0) { error(0, "Mime_parse returned 0, cannot continue"); goto error; } remove_crs(pap_content); if (!std_out) { fp1 = fopen(pap_content_file, "a"); if (fp1 == NULL) { error(0, "Cannot open the file for pap control message"); goto error; } octstr_print(fp1, pap_content); debug("test.mime", 0, "pap control message appended to the file"); fclose(fp1); } else { debug("test.mime", 0, "pap control message was"); octstr_dump(pap_content, 0); } remove_crs(push_data); if (!std_out) { fp2 = fopen(push_data_file, "a"); if (fp2 == NULL) { error(0, "Cannot open the push data file"); goto error; } push_content_file = octstr_create(""); octstr_append(push_content_file, octstr_imm("headers=")); while (gwlist_len(content_headers) > 0) { octstr_append(push_content_file, this_header = gwlist_extract_first(content_headers)); octstr_format_append(push_content_file, "%c", ' '); octstr_destroy(this_header); } octstr_append(push_content_file, octstr_imm(";\n")); octstr_append(push_content_file, octstr_imm("content=")); octstr_append(push_content_file, push_data); octstr_append(push_content_file, octstr_imm(";\n")); octstr_print(fp2, push_content_file); debug("test.mime", 0, "push content appended to the file"); fclose(fp2); } else { debug("test.mime", 0, "Content headers were"); http_header_dump(content_headers); debug("test.mime", 0, "And push content itself"); octstr_dump(push_data, 0); } if (rdf_content != NULL) remove_crs(rdf_content); if (!std_out && rdf_content != NULL) { fp3 = NULL; if (rdf_content != NULL) { fp3 = fopen(rdf_content_file, "a"); if (fp3 == NULL) { error(0, "Cannot open the rdf file"); goto cerror; } octstr_print(fp3, rdf_content); debug("test.mime", 0, "push caps message appended to the file"); fclose(fp3); } } else { if (rdf_content != NULL) { debug("test.mime", 0, "push caps message was"); octstr_dump(rdf_content, 0); } } octstr_destroy(boundary); octstr_destroy(mime_content); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(rdf_content); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(push_content_file); gwlib_shutdown(); info(0, "MIME data parsed successfully"); return 0; no_parse: octstr_destroy(mime_content); octstr_destroy(pap_osname); octstr_destroy(data_osname); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); gwlib_shutdown(); panic(0, "Stopping"); error: octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); octstr_destroy(rdf_content); gwlib_shutdown(); panic(0, "Stopping"); cerror: octstr_destroy(mime_content); gwlist_destroy(source_parts, octstr_destroy_item); octstr_destroy(boundary); octstr_destroy(pap_content); octstr_destroy(push_data); octstr_destroy(push_content_file); octstr_destroy(pap_osname); octstr_destroy(data_osname); http_destroy_headers(content_headers); octstr_destroy(rdf_content); gwlib_shutdown(); panic(0, "Stopping"); /* return after panic always required by gcc */ return 1; }
/* MO related function */ static void brunet_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars) { ConnData *conndata = conn->data; Octstr *user, *from, *to, *text, *udh, *date, *type; Octstr *retmsg; int mclass, mwi, coding, validity, deferred; List *reply_headers; int ret; mclass = mwi = coding = validity = deferred = 0; user = http_cgi_variable(cgivars, "CustomerId"); from = http_cgi_variable(cgivars, "MsIsdn"); to = http_cgi_variable(cgivars, "Recipient"); text = http_cgi_variable(cgivars, "SMMO"); udh = http_cgi_variable(cgivars, "XSer"); date = http_cgi_variable(cgivars, "DateReceived"); type = http_cgi_variable(cgivars, "MessageType"); debug("smsc.http.brunet", 0, "HTTP[%s]: Received a request", octstr_get_cstr(conn->id)); if (user == NULL || octstr_compare(user, conndata->username) != 0) { error(0, "HTTP[%s]: Authorization failure. CustomerId was <%s>.", octstr_get_cstr(conn->id), octstr_get_cstr(user)); retmsg = octstr_create("Authorization failed for MO submission."); } else if (from == NULL || to == NULL || text == NULL) { error(0, "HTTP[%s]: Insufficient args.", octstr_get_cstr(conn->id)); retmsg = octstr_create("Insufficient arguments, rejected."); } else { Msg *msg; msg = msg_create(sms); debug("smsc.http.brunet", 0, "HTTP[%s]: Received new MO SMS.", octstr_get_cstr(conn->id)); msg->sms.sender = octstr_duplicate(from); msg->sms.receiver = octstr_duplicate(to); msg->sms.msgdata = octstr_duplicate(text); msg->sms.udhdata = octstr_duplicate(udh); msg->sms.smsc_id = octstr_duplicate(conn->id); msg->sms.time = time(NULL); /* XXX maybe extract from DateReceived */ msg->sms.mclass = mclass; msg->sms.mwi = mwi; msg->sms.coding = coding; msg->sms.validity = validity; msg->sms.deferred = deferred; ret = bb_smscconn_receive(conn, msg); if (ret == -1) retmsg = octstr_create("Status=1"); else retmsg = octstr_create("Status=0"); } reply_headers = gwlist_create(); http_header_add(reply_headers, "Content-Type", "text/plain"); debug("smsc.http.brunet", 0, "HTTP[%s]: Sending reply `%s'.", octstr_get_cstr(conn->id), octstr_get_cstr(retmsg)); http_send_reply(client, HTTP_OK, reply_headers, retmsg); octstr_destroy(retmsg); http_destroy_headers(reply_headers); }
/* MT related function */ static int brunet_send_sms(SMSCConn *conn, Msg *sms) { ConnData *conndata = conn->data; Octstr *url, *tid, *xser; List *headers; char id[UUID_STR_LEN + 1]; int dcs; /* * Construct TransactionId. * Beware that brunet needs an "clean" octstr representation, * without the dashes in the string. So remove them. */ uuid_unparse(sms->sms.id, id); tid = octstr_create(id); octstr_replace(tid, octstr_imm("-"), octstr_imm("")); /* form the basic URL */ url = octstr_format("%S?MsIsdn=%E&Originator=%E", conndata->send_url, sms->sms.receiver, sms->sms.sender); /* * We use &binfo=<foobar> from sendsms interface to encode * additional paramters. If a mandatory value is not set, * a default value is applied */ if (octstr_len(sms->sms.binfo)) { octstr_url_decode(sms->sms.binfo); octstr_format_append(url, "&%S", sms->sms.binfo); } /* CustomerId */ if (octstr_search(url, octstr_create("CustomerId="), 0) == -1) { octstr_format_append(url, "&CustomerId=%S", conndata->username); } /* TransactionId */ if (octstr_search(url, octstr_create("TransactionId="), 0) == -1) { octstr_format_append(url, "&TransactionId=%S", tid); } /* SMSCount */ if (octstr_search(url, octstr_create("SMSCount="), 0) == -1) { octstr_format_append(url, "&%s", "SMSCount=1"); } /* ActionType */ if (octstr_search(url, octstr_create("ActionType="), 0) == -1) { octstr_format_append(url, "&%s", "ActionType=A"); } /* ServiceDeliveryType */ if (octstr_search(url, octstr_create("ServiceDeliveryType="), 0) == -1) { octstr_format_append(url, "&%s", "ServiceDeliveryType=P"); } /* if coding is not set and UDH exists, assume DC_8BIT * else default to DC_7BIT */ if (sms->sms.coding == DC_UNDEF) sms->sms.coding = octstr_len(sms->sms.udhdata) > 0 ? DC_8BIT : DC_7BIT; if (sms->sms.coding == DC_8BIT) octstr_format_append(url, "&MessageType=B&Text=%H", sms->sms.msgdata); else octstr_format_append(url, "&MessageType=S&Text=%E", sms->sms.msgdata); dcs = fields_to_dcs(sms, (sms->sms.alt_dcs != SMS_PARAM_UNDEFINED ? sms->sms.alt_dcs : 0)); /* XSer processing */ xser = octstr_create(""); /* XSer DCS values */ if (dcs != 0 && dcs != 4) octstr_format_append(xser, "0201%02x", dcs & 0xff); /* add UDH header */ if (octstr_len(sms->sms.udhdata)) { octstr_format_append(xser, "01%02x%H", octstr_len(sms->sms.udhdata), sms->sms.udhdata); } if (octstr_len(xser) > 0) octstr_format_append(url, "&XSer=%S", xser); octstr_destroy(xser); headers = http_create_empty_headers(); debug("smsc.http.brunet", 0, "HTTP[%s]: Sending request <%s>", octstr_get_cstr(conn->id), octstr_get_cstr(url)); /* * Brunet requires an SSL-enabled HTTP client call, this is handled * transparently by the Kannel HTTP layer module. */ http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, NULL, 0, sms, NULL); octstr_destroy(url); octstr_destroy(tid); http_destroy_headers(headers); return 0; }
Numhash *numhash_create(char *seek_url) { int loc, lines = 0; List *request_headers, *reply_headers; Octstr *url, *final_url, *reply_body; Octstr *type, *charset; char *data, *ptr, numbuf[100]; int status; Numhash *table; url = octstr_create(seek_url); request_headers = gwlist_create(); status = http_get_real(HTTP_METHOD_GET, url, request_headers, &final_url, &reply_headers, &reply_body); octstr_destroy(url); octstr_destroy(final_url); gwlist_destroy(request_headers, NULL); if (status != HTTP_OK) { http_destroy_headers(reply_headers); octstr_destroy(reply_body); error(0, "Cannot load numhash!"); return NULL; } http_header_get_content_type(reply_headers, &type, &charset); octstr_destroy(charset); http_destroy_headers(reply_headers); if (octstr_str_compare(type, "text/plain") != 0) { octstr_destroy(reply_body); error(0, "Strange content type <%s> for numhash - expecting 'text/plain'" ", operatiom fails", octstr_get_cstr(type)); octstr_destroy(type); return NULL; } octstr_destroy(type); ptr = data = octstr_get_cstr(reply_body); while(*ptr) { if (*ptr == '\n') lines++; ptr++; } debug("numhash", 0, "Total %d lines in %s", lines, seek_url); table = numhash_init(lines+10, NUMHASH_AUTO_HASH); /* automatic hash */ /* now, parse the number information */ lines = 0; while((ptr = strchr(data, '\n'))) { /* each line is ended with linefeed */ *ptr = '\0'; while(*data != '\0' && isspace(*data)) data++; if (*data != '#') { loc = 0; while (*data != '\0') { if (isdigit(*data)) numbuf[loc++] = *data; else if (*data == ' ' || *data == '+' || *data == '-') ; else break; data++; } if (loc) { numbuf[loc] = '\0'; numhash_add_number(table, numbuf); lines++; } else warning(0, "Corrupted line '%s'", data); } data = ptr+1; /* next row... */ } octstr_destroy(reply_body); info(0, "Read from <%s> total of %ld numbers", seek_url, table->number_total); return table; }
static void start_push(Octstr *rcpt_to, int isphonenum, MmsEnvelope *e, MmsMsg *msg) { List *pheaders; static unsigned char ct; /* Transaction counter -- do we need it? */ Octstr *to = NULL; Octstr *pduhdr = octstr_create(""); Octstr *s = NULL; info(0, "mms2mobile.startpush: notification to %s\n", octstr_get_cstr(rcpt_to)); if (!rcpt_to) { error(0, "mobilesender: Queue entry %s has no recipient address!", e->xqfname); goto done; } else to = octstr_duplicate(rcpt_to); ct++; octstr_append_char(pduhdr, ct); /* Pushd id */ octstr_append_char(pduhdr, 0x06); /* PUSH */ #if 1 octstr_append_char(pduhdr, 1 + 1 + 1); octstr_append_char(pduhdr, 0xbe); /* content type. */ #else octstr_append_char(pduhdr, 1 + 1 + sizeof "application/vnd.wap.mms-message"); /*header length. */ octstr_append_cstr(pduhdr, "application/vnd.wap.mms-message"); octstr_append_char(pduhdr, 0x0); /* string terminator. */ #endif octstr_append_char(pduhdr, 0xaf); /* push application ID header and value follows. */ octstr_append_char(pduhdr, 0x84); /* ... */ s = mms_tobinary(msg); if (isphonenum) { Octstr *url; octstr_url_encode(to); octstr_url_encode(s); #if 0 octstr_dump(pduhdr, 0); #endif octstr_url_encode(pduhdr); url = octstr_format("%S&text=%S%S&to=%S&udh=%%06%%05%%04%%0B%%84%%23%%F0", settings->sendsms_url, pduhdr, s, to); pheaders = http_create_empty_headers(); http_header_add(pheaders, "Connection", "close"); http_header_add(pheaders, "User-Agent", MM_NAME "/" MMSC_VERSION); http_start_request(httpcaller, HTTP_METHOD_GET, url, pheaders, NULL, 0, e, NULL); http_destroy_headers(pheaders); octstr_destroy(url); } else { /* An IP Address: Send packet, forget. */ Octstr *addr = udp_create_address(to, WAPPUSH_PORT); int sock = udp_client_socket(); if (sock > 0) { MmsEnvelopeTo *xto = gwlist_get(e->to,0); octstr_append(pduhdr, s); #if 0 octstr_dump(pduhdr, 0); #endif udp_sendto(sock, pduhdr, addr); close(sock); /* ?? */ mms_log2("Notify", octstr_imm("system"), to, -1, e ? e->msgId : NULL, NULL, NULL, "MM1", NULL,NULL); e = update_env_success(e, xto); } else { e = update_env_failed(e); error(0, "push to %s:%d failed: %s", octstr_get_cstr(to), WAPPUSH_PORT, strerror(errno)); } octstr_destroy(addr); if (e) settings->qfs->mms_queue_free_env(e); } done: octstr_destroy(to); octstr_destroy(pduhdr); octstr_destroy(s); }
/* 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; }