Example #1
0
/*
 * Transfer entity headers of a body part (it is, from the content entity) 
 * to a header list. Push Message, chapter 6.2.1.10 states that Content-Type
 * header is mandatory. 
 * Message proper starts after first empty line. We search only to it, and
 * remove the line here.
 * Return 0 when error, 1 otherwise. In addition, return the modified body
 * part and content headers.
 */
static int pass_data_headers(Octstr **body_part, List **data_headers)
{
    *data_headers = http_create_empty_headers();

    if (check_data_content_type_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
        warning(0, "MIME: pass_data_headers: Content-Type header missing"); 
        return 0;
    }
        
    if (pass_optional_header(body_part, "Content-Transfer-Encoding", data_headers,
            octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_optional_header(body_part, "Content-ID", data_headers, octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_optional_header(body_part, "Content-Description", data_headers, 
            octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_extension_headers(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0)
        goto operror;
   
    octstr_delete(*body_part, 0, octstr_len(octstr_imm("\r\n")));   

    return 1;

operror:
    warning(0, "MIME: pass_data_headers: an unparsable optional header");
    return 0;
}
Example #2
0
static List *push_headers_create(size_t content_len)
{
    List *push_headers;
    Octstr *mos;

    mos = NULL;
    push_headers = http_create_empty_headers();
    if (use_hardcoded)
        http_header_add(push_headers, "Content-Type", "multipart/related;" 
                        " boundary=asdlfkjiurwgasf; type=\"application/xml\"");
    else
        http_header_add(push_headers, "Content-Type", 
                        octstr_get_cstr(mos = make_multipart_value(boundary)));
    if (use_headers)
        http_add_basic_auth(push_headers, username, password);
    add_push_application_id(&push_headers, appid_flag, use_string);
    add_connection_header(&push_headers, connection);
    if (use_dlr_mask)
        add_dlr_mask(&push_headers, dlr_mask);
    if (use_dlr_url)
        add_dlr_url(&push_headers, dlr_url);

    octstr_destroy(mos);

    /* add initiator... */
    if (initiator_uri)
	http_header_add(push_headers, "X-Wap-Initiator-URI",
			octstr_get_cstr(initiator_uri));

    return push_headers;
}
Example #3
0
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;
}
Example #4
0
File: mime.c Project: frese/mbuni
MIMEEntity *mime_entity_create(void) 
{
    MIMEEntity *e;

    e = gw_malloc(sizeof(MIMEEntity));
    e->headers = http_create_empty_headers();
    e->multiparts = gwlist_create();
    e->body = NULL;
    e->start = NULL;

    return e;
}
Example #5
0
static List *unpack_new_headers(WSPMachine *sm, Octstr *hdrs) {
	List *new_headers;

	if (hdrs && octstr_len(hdrs) > 0) {
		new_headers = wsp_headers_unpack(hdrs, 0);
		if (sm->http_headers == NULL)
			sm->http_headers = http_create_empty_headers();
		http_header_combine(sm->http_headers, new_headers);
		return new_headers;
	}
	return NULL;
}
Example #6
0
/* 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;
}
/*
 * Transfer entity headers of a body part (it is, from the content entity) 
 * to a header list. Push Message, chapter 6.2.1.10 states that Content-Type
 * header is mandatory. 
 * Message proper starts after first empty line. We search only to it, and
 * remove the line here.
 * Return 0 when error, 1 otherwise. In addition, return the modified body
 * part and content headers.
 */
static int pass_data_headers(Octstr **body_part, List **data_headers)
{
    *data_headers = http_create_empty_headers();

    /* Transform X-WAP-Application headers as per PPG 6.1.2.1.
     * Note that missing header means that wml.ua is assumed. */
    if (check_data_x_wap_application_id_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
    	warning(0, "MIME: %s: X-Wap-Application-Id header missing, assuming 'wml.ua'", __func__);
    	gwlist_append(*data_headers, octstr_create("X-Wap-Application-Id: wml.ua"));
    }

    if (check_data_content_type_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
        warning(0, "MIME: %s: Content-Type header missing", __func__);
        return 0;
    }
        
    if (pass_optional_header(body_part, "Content-Transfer-Encoding", data_headers,
            octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_optional_header(body_part, "Content-ID", data_headers, octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_optional_header(body_part, "Content-Description", data_headers, 
            octstr_imm("\r\n\r\n")) < 0)
        goto operror;
    if (pass_extension_headers(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0)
        goto operror;
   
    /*
     * XXX: TODO: This assumes that there are no further headers prefixing
     * the MIME body. Which MAY not be the case. We SHOULD rather move all
     * headers to the data_headers and ensure by this that there are no
     * left overs.
     */
    octstr_delete(*body_part, 0, octstr_len(octstr_imm("\r\n")));   

    return 1;

operror:
    warning(0, "MIME: pass_data_headers: an unparseable optional header");
    return 0;
}
Example #8
0
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);
     }
}
Example #9
0
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;
}
Example #10
0
static List *make_reply_headers(WSPMachine *m)
{
    List *headers;
    Octstr *encoding_version;

    /* Add all server wsp level hop-by-hop headers. Currently only 
     * Encoding-Version, as defined by wsp, chapter 8.4.2.70. 
     * What headers belong to which version is defined in appendix A,
     * table 39.. 
    encoding_version = request_version = NULL;
     * Essentially, if the client sends us an Encoding-Version
     * higher than ours (1.3) we send our version number to it,
     * if it is lower, we left version number intact. */
    /* First the case that we have no Encoding-Version header at all. 
     * This case we must assume that the client supports version 1.2
     * or lower. */

    headers = http_create_empty_headers();
    encoding_version = wsp_encoding_version_to_string(m->encoding_version);
    http_header_add(headers, "Encoding-Version", octstr_get_cstr(encoding_version));
    octstr_destroy(encoding_version);

    return headers;
}
Example #11
0
/* 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;
}
Example #12
0
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;
}
Example #13
0
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);
}
Example #14
0
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;
}
Example #15
0
/* XXX Returns msgid in mmsc or NULL if error. Caller uses this for DLR issues. 
 * Caller must make sure throughput issues
 * are observed!
 * Don't remove from queue on fail, just leave it to expire. 
 */
static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, 
			    Octstr *transid,
			    Octstr *linkedid, 
			    char *vasid,
			    Octstr *service_code,
			    List *hdrs,
			    MmsMsg *m, Octstr **error,
			    List **errl,
			    int *retry)
{
     Octstr *ret = NULL;
     int mtype = mms_messagetype(m);
     int hstatus = HTTP_OK, tstatus  = -1;
     List *xto = gwlist_create();
     MSoapMsg_t *mreq = NULL, *mresp = NULL;
     List *rh = NULL, *ph = NULL;
     Octstr *body = NULL, *rbody = NULL, *url = NULL; 
     Octstr *s;
     char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL);

     mms_info(0, "MM7", mmc->id,  "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s", 
	  mmc->id ? octstr_get_cstr(mmc->id) : "", 
	  mms_message_type_to_cstr(mtype), 
	  octstr_get_cstr(from), octstr_get_cstr(to));    
     
     gwlist_append(xto, to);
     
     if ((mreq = mm7_mmsmsg_to_soap(m, (mmc == NULL || mmc->no_senderaddress == 0) ? from : NULL, 
				    xto, transid,
				    service_code, 
				    linkedid, 
				    1, octstr_get_cstr(mmc->vasp_id), xvasid, NULL, 0,/* UA N/A on this side. */
				    hdrs)) == NULL) {
	  *error = octstr_format("Failed to convert Msg[%S] 2 SOAP message!",
				 mms_message_type_to_string(mtype));
	  goto done1;
     }
     
     if (mm7_soapmsg_to_httpmsg(mreq, &mmc->ver, &rh, &body) < 0) {
	  *error = octstr_format("Failed to convert SOAP message to HTTP Msg!");
	  goto done1;
     } 

     if (hdrs)
	  http_header_combine(rh, hdrs);  /* If specified, then update and pass on. */
     
     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);
	  goto done1;
     }
     
     if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) {
	  *error = octstr_format("Failed to parse MMSC[url=%S, id=%S]  response!",
				 mmc->mmsc_url,  mmc->id);
	  goto done1;
     } 

     if (errl) { /* Pick up status stuff -- for DLR */
	  if (*errl == NULL)
	       *errl = http_create_empty_headers();
	  if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusText"))) != NULL) {	  
	       http_header_add(*errl, "X-Mbuni-StatusText", octstr_get_cstr(s));
	       octstr_destroy(s);
	  }

	  if ((s = mm7_soap_header_value(mresp, octstr_imm("Details"))) != NULL) {	  
	       http_header_add(*errl, "X-Mbuni-StatusDetails", octstr_get_cstr(s));
	       octstr_destroy(s);
	  }
     }

     /* Now look at response code and use it to tell you what you want. */
     if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) {
	  tstatus = atoi(octstr_get_cstr(s));
	  octstr_destroy(s);
     } else if ((s = mm7_soap_header_value(mresp, octstr_imm("faultstring"))) != NULL) {
	  tstatus = atoi(octstr_get_cstr(s));
	  octstr_destroy(s);
     } else
	  tstatus = MM7_SOAP_FORMAT_CORRUPT; 
     

     if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) {
	  Octstr *detail =  mm7_soap_header_value(mresp, octstr_imm("Details"));
	  char *tmp = (char *)mms_soap_status_to_cstr(tstatus);
	  if (detail == NULL)
	       detail = mm7_soap_header_value(mresp, octstr_imm("faultcode"));
	  ret = NULL;
	  mms_info(0, "MM7", mmc->id, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]", 
	       mmc ? octstr_get_cstr(mmc->id) : "", 
	       tstatus, tmp ? tmp : "", 
	       detail ? octstr_get_cstr(detail) : "");

	  *error = octstr_format("Failed to deliver to MMC[url=%S, id=%S], status=[%d=>%s]!",
				 mmc->mmsc_url, 
				 mmc->id,
				 tstatus, 
				 tmp ? tmp : "");	  
	  octstr_destroy(detail);	  
     } else {	  
	  ret = mm7_soap_header_value(mresp, octstr_imm("MessageID"));	  
	  mms_info(0, "MM7", NULL, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id), 
	       tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)");
     }


     if (ret)
	  mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
done1:
     *retry = (ret == NULL && (!MM7_SOAP_CLIENT_ERROR(tstatus) || tstatus < 0));
     
     mm7_soap_destroy(mreq);
     mm7_soap_destroy(mresp);	  
     http_destroy_headers(rh);
     octstr_destroy(body);
     http_destroy_headers(ph);
     octstr_destroy(rbody);
     octstr_destroy(url);

     gwlist_destroy(xto, NULL);

     return ret;
}
Example #16
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;
}
Example #17
0
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;
}
Example #18
0
/* 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;
}
Example #19
0
static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e, Octstr *to,
			  Octstr *orig_transid,

			  MmsMsg *m, 
			  Octstr **new_msgid,
			  List **errhdrs) 
{
     Octstr *id = NULL, *groupid = NULL;
     int ret = 0, retry  = 0;
     double throughput = 0;
     Octstr *from = e->from;
     Octstr *transid = e->msgId;
     Octstr *linkedid = e->token; /* token = linkedid */
     char *vasid = e->vasid ? octstr_get_cstr(e->vasid) : NULL;
     Octstr *service_code = e->vaspid;
     Octstr *dlr_url = e->url1;
     Octstr *rr_url = e->url2;
     List *hdrs = e->hdrs;
     
     mutex_lock(mmc->mutex); { /* Grab a lock on it. */
	  Octstr *err = NULL;
	  if (mmc->type == SOAP_MMSC)
	       id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, hdrs, m, &err, errhdrs, &retry);
	  else if (mmc->type == EAIF_MMSC)
	       id = mm7eaif_send(mmc, from, to, transid, vasid, hdrs, m, &err, &retry);
	  else if (mmc->type == HTTP_MMSC)
	       id = mm7http_send(mmc, from, to, m, &err, &retry);
	  else if (mmc->type == CUSTOM_MMSC && mmc->custom_started) 
	       id = mmc->fns->send_msg(mmc->data, 
				       from, to, transid, linkedid, vasid, 
				       service_code, m, hdrs, &err, &retry);
	  else 
	       mms_error_ex("MT", 0,  "MM7", mmc->id, "MMC[%s] of unknown type, can't send!", 
		     mmc->id ? octstr_get_cstr(mmc->id) : ""); 	       
	
	  throughput = mmc->throughput;
	  groupid = mmc->group_id ? octstr_duplicate(mmc->group_id) : NULL;
	  
	  if (err && errhdrs) {
	       if (*errhdrs == NULL) 
		    *errhdrs = http_create_empty_headers();
	       http_header_add(*errhdrs, "X-Mbuni-Error", octstr_get_cstr(err));
	  }
	  octstr_destroy(err);
     }  mutex_unlock(mmc->mutex);  /* release lock */

     if (id) {
	  if (dlr_url)  /* remember the url's for reporting purposes. */
	       mms_dlr_url_put(id, "delivery-report", groupid, dlr_url, orig_transid);
	  if (rr_url)
	       mms_dlr_url_put(id, "read-report", groupid, rr_url, orig_transid);	  
	  ret = MMS_SEND_OK;
     } else 
	  ret = retry ? MMS_SEND_ERROR_TRANSIENT : MMS_SEND_ERROR_FATAL; 
     
     *new_msgid = id;
          
     octstr_destroy(groupid);
     if (throughput > 0) 
	  gwthread_sleep(1.0/throughput);          
     return ret;
}
Example #20
0
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;
}
Example #21
0
static void do_mm1_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;     
     
     if (!rcpt_to) {
	  mms_error(0, "MM1", NULL, "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 + strlen("application/vnd.wap.mms-message") + 1); /*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_format("%S&text=%E%E&to=%E&udh=%%06%%05%%04%%0B%%84%%23%%F0",	
				      settings->sendsms_url, pduhdr, s, to);     
	  int status;
	  List *rph  = NULL;
	  Octstr *rbody = NULL;
	  MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
	  
	  pheaders = http_create_empty_headers();
	  http_header_add(pheaders, "Connection", "close");
	  http_header_add(pheaders, "User-Agent", MM_NAME "/" MMSC_VERSION);	       
	  
	  if ((status = mms_url_fetch_content(HTTP_METHOD_GET, url, pheaders, NULL, &rph, &rbody)) < 0 ||
	      http_status_class(status) != HTTP_STATUS_SUCCESSFUL) {
	       
	       mms_error(0,  "MM1", NULL, " Push[%s] from %s, to %s, failed, HTTP code => %d", e->xqfname, 
			 octstr_get_cstr(e->from), octstr_get_cstr(to), status);	       

	       e = update_env(e,xto,0);
	  } else {	 /* Successful push. */      

	       mms_log2("Notify", octstr_imm("system"), to, 
			-1, e ? e->msgId : NULL, NULL, NULL, "MM1", NULL,NULL);
	       e = update_env(e, xto, 1);	       
	  }     
	  
	  http_destroy_headers(pheaders);
	  http_destroy_headers(rph);
	  octstr_destroy(rbody);
	  octstr_destroy(url);
     } else { /* An IP Address: Send packet, forget. */
	  Octstr *addr = udp_create_address(to, WAPPUSH_PORT);
	  int sock = udp_client_socket();
	  MmsEnvelopeTo *xto = gwlist_get(e->to,0);
	  
	  if (sock > 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(e, xto, 1);
	  } else {
	       e = update_env(e, xto, 0);
	       mms_error(0,  "MM1", NULL, "push to %s:%d failed: %s", 
			 octstr_get_cstr(to), WAPPUSH_PORT, strerror(errno));
	  }
	  octstr_destroy(addr);
     }
 done:
     octstr_destroy(to);
     octstr_destroy(pduhdr);
     octstr_destroy(s);
     
     if (e)
	  settings->qfs->mms_queue_free_env(e);     
}
Example #22
0
Numhash *numhash_create(const 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 = http_create_empty_headers();
    status = http_get_real(HTTP_METHOD_GET, url, request_headers, &final_url,
			    &reply_headers, &reply_body);
    octstr_destroy(url);
    octstr_destroy(final_url);
    http_destroy_headers(request_headers);

    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;
}
Example #23
0
/* 
 * Attempt to read an envelope from queue file:
 * - opens and locks the file. 
 * - if the lock succeeds, check that file hasn't changed since opening. If it has
 *   return NULL (i.e. file is being processed elsewhere -- race condition), otherwise read it.
 * - If should block is 1, then does a potentially blocking attempt to lock the file.
 */
static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldblock)
{
     Octstr *fname;
     int fd;
     Octstr *qdata, *s;
     ParseContext *p;
     MmsEnvelope *e;
     int okfile = 0;
     char subdir[64];
     char realqf[QFNAMEMAX];
     char xqf[QFNAMEMAX+64];
     struct qfile_t *qfs;
     
     get_subdir(qf, subdir, realqf); /* break it down... */

     fname = octstr_format( "%.128s/%s%s", mms_queuedir, subdir, realqf);
     
     strncpy(xqf, octstr_get_cstr(fname), sizeof xqf);
     
#ifdef SunOS
     if ((fd = open(octstr_get_cstr(fname), O_RDWR)) < 0) {
#else
     if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) {
#endif
		debug("",0,"mms_queue_readenvelope: could not open file %s", octstr_get_cstr(fname));
	  octstr_destroy(fname);
	  return NULL;
     } else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) {
		debug("",0,"mms_queue_readenvelope: could not lock file %s", octstr_get_cstr(fname));
	  unlock_and_close(fd);
	  octstr_destroy(fname);
	  return NULL;
     }

	debug("",0,"locked and opened file: %s", octstr_get_cstr(fname));
     
     e = mms_queue_create_envelope(NULL, NULL, 
				   NULL, 
				   NULL, NULL, 
				   0, 0, 
				   NULL, 
				   NULL, NULL, 
				   NULL, NULL, 
				   NULL,
				   0, 
				   NULL, 
				   NULL,
				   qf,
				   NULL,
				   sizeof (struct qfile_t), NULL);
     qfs = e->qfs_data;
     
     qfs->fd = fd;
     strncpy(qfs->name, realqf, sizeof qfs->name);
     strncpy(qfs->subdir, subdir, sizeof qfs->subdir);
     strncpy(qfs->dir, mms_queuedir, sizeof qfs->dir);

     qdata = octstr_read_file(octstr_get_cstr(fname));
     octstr_destroy(fname);
     if (qdata == NULL)
	  qdata = octstr_imm("");
     p = parse_context_create(qdata);
     
     for (s = parse_get_line(p); s;  
	  s = parse_get_line(p)) {
	  char *line = octstr_get_cstr(s);
	  int ch = line[0];
	  char *res = line + 1;
	  char *ptmp;

	  switch (ch) {
	       Octstr *t;
	       MmsEnvelopeTo *to;
	  case 'T':
	       t = octstr_create(res);
	       e->msgtype = mms_string_to_message_type(t);
	       octstr_destroy(t);
	       if (e->msgtype < 0) {
		    e->msgtype = 0;
		    error(0, "mms_queueread: Unknown MMS message type (%s) in file %s, skipped!\n",
			  res, xqf);
	       }
	       break;
	  case 'I':
	       e->msgId = octstr_create(res);	       
	       break;
	  case 'i':
	       strncpy(e->src_interface, res, sizeof e->src_interface);
	       break;
	  case 'F':
	       e->from = octstr_create(res);
	       if (mms_validate_address(e->from) != 0) {
		    warning(0, "mms_queueread: Mal-formed address [%s] in file %s! "
			    "Attempting fixup.", res, xqf);
		    _mms_fixup_address(&e->from, NULL, NULL, 1);
	       }
	       break;
	  case 'R':

	       t = octstr_create(res);
	       if (mms_validate_address(t) != 0) {
		    warning(0, "mms_queueread: Mal-formed address [%s] in file %s! " 
			    "Attempting fixup.", res, xqf);
		    _mms_fixup_address(&t, NULL, NULL, 1);
	       }
	       to = gw_malloc(sizeof *to);
	       to->rcpt = t;
	       to->process = 1;	       
	       gwlist_append(e->to, to);
	       break;
	  case 'C':
	       e->created = atol(res);
	       break;
	  case 'L':
	       e->lasttry = atol(res);
	       break;
	  case 'D':
	       e->sendt = atol(res);
	       break;
	  case 'X':
	       e->expiryt = atol(res);
	       break;
	  case 'N':
	       e->attempts = atol(res);
	       break;
	  case 'P':
	       e->fromproxy = octstr_create(res);
	       break;
	  case 'M':
	       e->mdata = octstr_create(res);
	       break;
	  case 'p':
	       e->viaproxy = octstr_create(res);
	       break;
	  case 'S':
	       e->msize = atol(res);
	    break;
	  case 's':
	       e->subject = octstr_create(res);
	       break;	
	  case 't':
	       e->token = octstr_create(res);
	       break;
	  case 'f':
	       e->lastaccess = atol(res);
	       break;
	  case 'b':
	       e->bill.billed = 1;
	       e->bill.amt = atof(res);
	    break;
	  case 'r':
	       e->dlr = 1;
	       break;
	  case 'V':
	       e->vaspid = octstr_create(res);
	       break;
	  case 'v':
	       e->vasid = octstr_create(res);
	       break;

	  case 'U':
	       e->url1 = octstr_create(res);
	       break;

	  case 'u':
	       e->url2 = octstr_create(res);
	       break;
	  case 'H':
	       if (e->hdrs == NULL)
		    e->hdrs = http_create_empty_headers();
	       if ((ptmp = index(res, ':')) == NULL)
		    error(0, "Incorrectly formatted line %s in queue file %s!",
			  line, xqf);
	       else {
		    char *value = ptmp + 1;
		    char hname[512];
		    int xlen = (ptmp - res < sizeof hname) ? ptmp - res : -1 + sizeof hname;
		    strncpy(hname, res, xlen);
		    hname[xlen] = 0; /* terminate it. */
		    http_header_add(e->hdrs, hname, value);
	       }
	       break;
	  case '.':
	       okfile = 1;
	       break;
	  default:
	       error(0, "Unknown QF header %c in file %s!", ch, xqf);
	       break;
	  }
	  octstr_destroy(s);
	  if (okfile) 
	       break; /* We are done. */
     }
     parse_context_destroy(p);
     octstr_destroy(qdata);

     /* We should properly validate the queue file here. */
     if (!okfile) {
	  free_envelope(e,0);
	  e = NULL;
	  error(0, "Corrupt queue control file: %s",  xqf);
     }
     return e;     
}

/* Updates envelope to queue file:
 * - opens temp file
 * - writes output to temp file, if not new else writes directly.
 * - renames temp file to queue file (if not new)
 * This function doesn't check that this envelope is useless (i.e. no recipients)
 * - If function returns -1, caller should check errno for error.
 */
static int writeenvelope(MmsEnvelope *e, int newenv)
{
     Octstr *tfname = NULL;
     char *s;
     char buf[512];
     int fd;
     int i, n;
     int res = 0;
     struct qfile_t *qfs = e ? e->qfs_data : NULL;
     
     gw_assert(e);
     
     if (newenv)
	  fd = qfs->fd;
     else {
	  tfname = octstr_format( 
	       "%s/%s%c%s.%d", qfs->dir, qfs->subdir,
	       MTF, qfs->name + 1, random());
	  fd = open(octstr_get_cstr(tfname),
		    O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	  if (fd < 0 ) {
	       error(0, "mms_queueadd: Failed to open temp file %s: error = %s\n",
		     octstr_get_cstr(tfname), strerror(errno));
	       res = -1;
	       goto done;
	  } else if (mm_lockfile(fd, octstr_get_cstr(tfname), 0) != 0) { /* Lock it. */
	       error(0, "mms_queueadd: Failed lock  temp file %s: error = %s\n", 
		     octstr_get_cstr(tfname), strerror(errno));
	       res = -1;	  
	       goto done;
	  }
     }
	  
     /* Write out. */

     s = (char *)mms_message_type_to_cstr(e->msgtype);
     if (!s) {
	  error(0, "mms_queuewrite: Unknown MMS message type %d! Skipped\n", e->msgtype);
	  s = "";
     }
     _putline(fd, "T", s);
     
     if (e->msgId) 
	  _putline(fd, "I", octstr_get_cstr(e->msgId));

     if (e->src_interface[0])
	  _putline(fd, "i", e->src_interface);
     
     if (e->from)
	  _putline(fd, "F", octstr_get_cstr(e->from));

     if (e->to)
	  n = gwlist_len(e->to);
     else
	  n = 0;

     for (i = 0; i < n; i++) {
	  MmsEnvelopeTo *to = gwlist_get(e->to, i);
	  
	  if (to->process)	       
	       _putline(fd, "R", octstr_get_cstr(to->rcpt));
     }

     /* Output headers if any. */
     n = (e->hdrs) ? gwlist_len(e->hdrs) : 0;
     for (i = 0; i < n; i++) {
	  Octstr *h = NULL, *v = NULL;

	  http_header_get(e->hdrs, i, &h, &v);
	  if (h && v) {
	       Octstr *x = octstr_format("%s:%s", octstr_get_cstr(h), 
					 octstr_get_cstr(v));
	       _putline(fd, "H", octstr_get_cstr(x));
	       octstr_destroy(x);	       
	  }
	  if (h) octstr_destroy(h);
	  if (v) octstr_destroy(v);

     }

     sprintf(buf, "%ld", e->created);
     _putline(fd, "C", buf);

     if (e->lasttry) {
	  sprintf(buf, "%ld", e->lasttry);
	  _putline(fd, "L", buf);
     }

     if (e->sendt) {
	  sprintf(buf, "%ld", e->sendt);
	  _putline(fd, "D", buf);
     }

     if (e->expiryt) {
	  sprintf(buf, "%ld", e->expiryt);
	  _putline(fd, "X", buf);
     }

     if (e->attempts) {
	  sprintf(buf, "%ld", e->attempts);
	  _putline(fd, "N", buf);
     }

     if (e->lastaccess) {
	  sprintf(buf, "%ld", e->lastaccess);
	  _putline(fd, "f", buf);
     }

     sprintf(buf, "%ld", e->msize);
     _putline(fd, "S", buf);


     if (e->fromproxy) 
	  _putline(fd, "P", octstr_get_cstr(e->fromproxy));


     if (e->mdata) 
	  _putline(fd, "M", octstr_get_cstr(e->mdata));

     if (e->subject)
	  _putline(fd, "s", octstr_get_cstr(e->subject));
     

     if (e->viaproxy) 
	  _putline(fd, "p", octstr_get_cstr(e->viaproxy));

     if (e->token) 
	  _putline(fd, "t", octstr_get_cstr(e->token));
     

      if (e->vaspid) 
	  _putline(fd, "V", octstr_get_cstr(e->vaspid));
     
      if (e->vasid) 
	  _putline(fd, "v", octstr_get_cstr(e->vasid));
     
      if (e->url1) 
	  _putline(fd, "U", octstr_get_cstr(e->url1));

      if (e->url2) 
	  _putline(fd, "u", octstr_get_cstr(e->url2));

     if (e->dlr) 
	  _putline(fd, "r", "Yes");

     if (e->bill.billed) {
	  sprintf(buf, "%.3f", e->bill.amt);
	  _putline(fd,"b", buf);
     }

     _putline(fd, "", ".");

     fsync(fd); /* Sync data. */
     
     if (!newenv) { /* An update */
	  Octstr *qfname;
	 
	  qfname = octstr_format("%s/%s%s", qfs->dir, qfs->subdir, qfs->name);
	
	  if (rename(octstr_get_cstr(tfname), octstr_get_cstr(qfname)) < 0) {
	       error(0, "mms_queuewrite: Failed to rename %s to %s: error = %s\n", 
		     octstr_get_cstr(qfname), octstr_get_cstr(tfname), strerror(errno));

	       unlock_and_close(fd); /* Close new one, keep old one. */
		   res = -1;
	  } else { /* On success, new descriptor replaces old one and we close old one. */
	       unlock_and_close(qfs->fd);
	       qfs->fd = fd;
	  }
	  octstr_destroy(qfname);
     }

 done:
     octstr_destroy(tfname);
     return res;
}