Exemple #1
0
/*
 * check if the password matches. Return NULL if
 * it does (or is not required)
 */
static Octstr *httpd_check_authorization(List *cgivars, int status)
{
    Octstr *password;
    static double sleep = 0.01;

    password = http_cgi_variable(cgivars, "password");

    if (status) {
	if (ha_status_pw == NULL)
	    return NULL;

	if (password == NULL)
	    goto denied;

	if (octstr_compare(password, ha_password)!=0
	    && octstr_compare(password, ha_status_pw)!=0)
	    goto denied;
    }
    else {
	if (password == NULL || octstr_compare(password, ha_password)!=0)
	    goto denied;
    }
    sleep = 0.0;
    return NULL;	/* allowed */
denied:
    gwthread_sleep(sleep);
    sleep += 1.0;		/* little protection against brute force
				 * password cracking */
    return octstr_create("Denied");
}
Exemple #2
0
static Octstr *httpd_restart_smsc(List *cgivars, int status_type)
{
    Octstr *reply;
    Octstr *smsc;
    if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
    if ((reply = httpd_check_status())!= NULL) return reply;

    /* check if the smsc id is given */
    smsc = http_cgi_variable(cgivars, "smsc");
    if (smsc) {
        if (bb_restart_smsc(smsc) == -1)
            return octstr_format("Could not re-start smsc-id `%s'", octstr_get_cstr(smsc));
        else
            return octstr_format("SMSC `%s' re-started", octstr_get_cstr(smsc));
    } else
        return octstr_create("SMSC id not given");
}
Exemple #3
0
static Octstr *httpd_loglevel(List *cgivars, int status_type)
{
    Octstr *reply;
    Octstr *level;
    int new_loglevel;
    
    if ((reply = httpd_check_authorization(cgivars, 0))!= NULL) return reply;
    if ((reply = httpd_check_status())!= NULL) return reply;
 
    /* check if new loglevel is given */
    level = http_cgi_variable(cgivars, "level");
    if (level) {
        new_loglevel = atoi(octstr_get_cstr(level));
        log_set_log_level(new_loglevel);
        return octstr_format("log-level set to %d", new_loglevel);
    }
    else {
        return octstr_create("New level not given");
    }
}
Exemple #4
0
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);
}
Exemple #5
0
/* 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);
}
static void client_thread(void *arg) 
{
    HTTPClient *client;
    Octstr *body, *url, *ip;
    List *headers, *resph, *cgivars;
    HTTPCGIVar *v;
    Octstr *reply_body, *reply_type;
    unsigned long n = 0;
    int status, i;

    while (run) {
        client = http_accept_request(port, &ip, &url, &headers, &body, &cgivars);

        n++;
        if (client == NULL)
            break;

        info(0, "Request for <%s> from <%s>", 
             octstr_get_cstr(url), octstr_get_cstr(ip));
        if (verbose)
            debug("test.http", 0, "CGI vars were");

        /*
         * Don't use gwlist_extract() here, otherwise we don't have a chance
         * to re-use the cgivars later on.
         */
        for (i = 0; i < gwlist_len(cgivars); i++) {
            if ((v = gwlist_get(cgivars, i)) != NULL && verbose) {
                octstr_dump(v->name, 0);
                octstr_dump(v->value, 0);
            }
        }
    
        if (arg == NULL) {
            reply_body = octstr_duplicate(reply_text);
            reply_type = octstr_create("Content-Type: text/plain; "
                                       "charset=\"UTF-8\"");
        } else {
            reply_body = octstr_duplicate(arg);
            reply_type = octstr_create("Content-Type: text/vnd.wap.wml");
        }

        resph = gwlist_create();
        gwlist_append(resph, reply_type);

        status = HTTP_OK;

        /* check for special URIs and handle those */
        if (octstr_compare(url, octstr_imm("/quit")) == 0) {
	       run = 0;
        } else if (octstr_compare(url, octstr_imm("/whitelist")) == 0) {
	       octstr_destroy(reply_body);
            if (whitelist != NULL) {
                if (verbose) {
                    debug("test.http.server", 0, "we send a white list");
                    octstr_dump(whitelist, 0);
                }
                reply_body = octstr_duplicate(whitelist);
            } else {
	           reply_body = octstr_imm("");
	       }
        } else if (octstr_compare(url, octstr_imm("/blacklist")) == 0) {
            octstr_destroy(reply_body);
            if (blacklist != NULL) {
                if (verbose) {
                    debug("test.http.server", 0, "we send a blacklist");
                    octstr_dump(blacklist, 0);
                }
                reply_body = octstr_duplicate(blacklist);
            } else {
                reply_body = octstr_imm("");
            } 
        } else if (octstr_compare(url, octstr_imm("/save")) == 0) {
            /* safe the body into a temporary file */
            pid_t pid = getpid();
            FILE *f = fopen(octstr_get_cstr(octstr_format("/tmp/body.%ld.%ld", pid, n)), "w");
            octstr_print(f, body);
            fclose(f);
        } else if (octstr_compare(url, octstr_imm("/redirect/")) == 0) {
            /* provide us with a HTTP 302 redirection response
             * will return /redirect/<pid> for the location header 
             * and will return /redirect/ if cgivar loop is set to allow looping
             */
            Octstr *redirect_header, *scheme, *uri, *l;
            pid_t pid = getpid();

            uri = ((l = http_cgi_variable(cgivars, "loop")) != NULL) ?
                octstr_format("%s?loop=%s", octstr_get_cstr(url), 
                              octstr_get_cstr(l)) : 
                octstr_format("%s%ld", octstr_get_cstr(url), pid);

            octstr_destroy(reply_body);
            reply_body = octstr_imm("Here you got a redirection URL that you should follow.");
            scheme = ssl ? octstr_imm("https://") : octstr_imm("http://");
            redirect_header = octstr_format("Location: %s%s%s", 
                octstr_get_cstr(scheme),
                octstr_get_cstr(http_header_value(headers, octstr_imm("Host"))),
                octstr_get_cstr(uri));
            gwlist_append(resph, redirect_header);
            status = HTTP_FOUND; /* will provide 302 */
            octstr_destroy(uri);
        } else if (octstr_compare(url, octstr_imm("/mmsc")) == 0) {
            /* fake a M-Send.conf PDU which is using MMSEncapsulation as body */
            pid_t pid = getpid();
            FILE *f;
            gwlist_destroy(resph, octstr_destroy_item);
            octstr_destroy(reply_body);
            reply_type = octstr_create("Content-Type: application/vnd.wap.mms-message");
            reply_body = octstr_create("");
            octstr_append_from_hex(reply_body, 
                "8c81"              /* X-Mms-Message-Type: m-send-conf */
                "98632d3862343300"  /* X-Mms-Transaction-ID: c-8b43 */
                "8d90"              /* X-Mms-MMS-Version: 1.0 */
                "9280"              /* Response-status: Ok */
                "8b313331373939353434393639383434313731323400"
            );                      /* Message-Id: 13179954496984417124 */
            resph = gwlist_create();
            gwlist_append(resph, reply_type);
            /* safe the M-Send.req body into a temporary file */
            f = fopen(octstr_get_cstr(octstr_format("/tmp/mms-body.%ld.%ld", pid, n)), "w");
            octstr_print(f, body);
            fclose(f);
        }        
            
        if (verbose) {
            debug("test.http", 0, "request headers were");
            http_header_dump(headers);
            if (body != NULL) {
                debug("test.http", 0, "request body was");
                octstr_dump(body, 0);
            }
        }

        if (extra_headers != NULL)
        	http_header_combine(resph, extra_headers);

        /* return response to client */
        http_send_reply(client, status, resph, reply_body);

        octstr_destroy(ip);
        octstr_destroy(url);
        octstr_destroy(body);
        octstr_destroy(reply_body);
        http_destroy_cgiargs(cgivars);
        gwlist_destroy(headers, octstr_destroy_item);
        gwlist_destroy(resph, octstr_destroy_item);
    }

    octstr_destroy(whitelist);
    octstr_destroy(blacklist);
    debug("test.http", 0, "Working thread 'client_thread' terminates");
    http_close_all_ports();
}
Exemple #7
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;
}